(linenum→info "unix/slp.c:2238")

glibc/2.7/elf/dl-caller.c

    1: /* Check whether caller comes from the right place.
    2:    Copyright (C) 2004 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #include <assert.h>
   21: #include <ldsodefs.h>
   22: #include <stddef.h>
   23: #include <caller.h>
   24: #include <gnu/lib-names.h>
   25: 
   26: 
   27: int
   28: attribute_hidden
   29: _dl_check_caller (const void *caller, enum allowmask mask)
   30: {
   31:   static const char expected1[] = LIBC_SO;
   32:   static const char expected2[] = LIBDL_SO;
   33: #ifdef LIBPTHREAD_SO
   34:   static const char expected3[] = LIBPTHREAD_SO;
   35: #endif
   36:   static const char expected4[] = LD_SO;
   37: 
   38:   for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
   39:     for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
   40:          l = l->l_next)
   41:       if (caller >= (const void *) l->l_map_start
   42:           && caller < (const void *) l->l_text_end)
   43:         {
   44:           /* The address falls into this DSO's address range.  Check the
   45:              name.  */
   46:           if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
   47:             return 0;
   48:           if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
   49:             return 0;
   50: #ifdef LIBPTHREAD_SO
   51:           if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
   52:             return 0;
   53: #endif
   54:           if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
   55:             return 0;
   56: 
   57:           struct libname_list *runp = l->l_libname;
   58: 
   59:           while (runp != NULL)
   60:             {
   61:               if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
   62:                 return 0;
   63:               if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
   64:                 return 0;
   65: #ifdef LIBPTHREAD_SO
   66:               if ((mask & allow_libpthread)
   67:                   && strcmp (expected3, runp->name) == 0)
   68:                 return 0;
   69: #endif
   70:               if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
   71:                 return 0;
   72: 
   73:               runp = runp->next;
   74:             }
   75: 
   76:           break;
   77:         }
   78: 
   79:   /* Maybe the dynamic linker is not yet on the list.  */
   80:   if ((mask & allow_ldso) != 0
   81:       && caller >= (const void *) GL(dl_rtld_map).l_map_start
   82:       && caller < (const void *) GL(dl_rtld_map).l_text_end)
   83:     return 0;
   84: 
   85:   /* No valid caller.  */
   86:   return 1;
   87: }
Syntax (Markdown)