* posix/unistd.h: Move declaration of __libc_enable_secure to...
	* include/unistd.h: ...here.

	* elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt.
	* elf/dl-deps.c (expand_dst): Likewise.

	* elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW
	based on DT_FLAGS value.

	* elf/do-lookup.h: Remove reference_name parameter, add undef_map.
	Add test for symbols marked STV_HIDDEN.
	* elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter,
	add undef_map.  Compute reference_name locally.  Update call to
	do_lookup.
	(_dl_lookup_symbol_skip): Likewise.
	(_dl_lookup_versioned_symbol): Likewise.
	(_dl_lookup_versioned_symbol_skip): Likewise.
	* elf/dl-libc.c: Update call to _dl_lookup_*symbol.
	* elf/dl-runtime.c: Likewise.
	* elf/dl-sym.c: Likewise.
	* elf/dl-symbol.c: Likewise.
	* elf/ldsodefs.h: Adjust prototypes.

	* elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and
	handle appropriately.  Add comment about DT_TEXTREL.
	* elf/dl-runtime.c: Likewise.
This commit is contained in:
Ulrich Drepper 1999-07-23 22:58:50 +00:00
parent fc9cfb28c0
commit 06535ae948
14 changed files with 194 additions and 113 deletions

View File

@ -13,6 +13,33 @@
DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ. DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ.
Add DF_ORIGIN, DF_SYMBOLIC, DF_TEXTREL, and DF_BIND_NOW. Add DF_ORIGIN, DF_SYMBOLIC, DF_TEXTREL, and DF_BIND_NOW.
* posix/unistd.h: Move declaration of __libc_enable_secure to...
* include/unistd.h: ...here.
* elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt.
* elf/dl-deps.c (expand_dst): Likewise.
* elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW
based on DT_FLAGS value.
* elf/do-lookup.h: Remove reference_name parameter, add undef_map.
Add test for symbols marked STV_HIDDEN.
* elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter,
add undef_map. Compute reference_name locally. Update call to
do_lookup.
(_dl_lookup_symbol_skip): Likewise.
(_dl_lookup_versioned_symbol): Likewise.
(_dl_lookup_versioned_symbol_skip): Likewise.
* elf/dl-libc.c: Update call to _dl_lookup_*symbol.
* elf/dl-runtime.c: Likewise.
* elf/dl-sym.c: Likewise.
* elf/dl-symbol.c: Likewise.
* elf/ldsodefs.h: Adjust prototypes.
* elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and
handle appropriately. Add comment about DT_TEXTREL.
* elf/dl-runtime.c: Likewise.
1999-07-21 Roland McGrath <roland@baalperazim.frob.com> 1999-07-21 Roland McGrath <roland@baalperazim.frob.com>
* elf/dl-reloc.c (_dl_reloc_bad_type): New function. * elf/dl-reloc.c (_dl_reloc_bad_type): New function.

View File

@ -22,6 +22,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/param.h> #include <sys/param.h>
#include <elf/ldsodefs.h> #include <elf/ldsodefs.h>
@ -96,9 +97,15 @@ struct list
\ \
if (__cnt != 0) \ if (__cnt != 0) \
{ \ { \
char *__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, \ char *__newp; \
strlen (__str), \ \
__cnt)); \ /* DST must not appear in SUID/SGID programs. */ \
if (__libc_enable_secure) \
_dl_signal_error (0, __str, \
"DST not allowed in SUID/SGID programs"); \
\
__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str), \
__cnt)); \
\ \
__result = DL_DST_SUBSTITUTE (l, __str, __newp, 0); \ __result = DL_DST_SUBSTITUTE (l, __str, __newp, 0); \
\ \

View File

@ -82,9 +82,8 @@ do_dlsym (void *ptr)
{ {
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr; struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
args->ref = NULL; args->ref = NULL;
args->loadbase = _dl_lookup_symbol (args->name, &args->ref, args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref,
args->map->l_local_scope, args->map->l_local_scope, 0);
args->map->l_name, 0);
} }
static void static void

View File

@ -75,11 +75,11 @@ unsigned long int _dl_num_relocations;
ElfW(Addr) ElfW(Addr)
internal_function internal_function
_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
struct r_scope_elem *symbol_scope[], const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
const char *reference_name,
int reloc_type) int reloc_type)
{ {
const char *reference_name = undef_map ? undef_map->l_name : NULL;
const unsigned long int hash = _dl_elf_hash (undef_name); const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { NULL, NULL }; struct sym_val current_value = { NULL, NULL };
struct r_scope_elem **scope; struct r_scope_elem **scope;
@ -88,8 +88,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
/* Search the relevant loaded objects for a definition. */ /* Search the relevant loaded objects for a definition. */
for (scope = symbol_scope; *scope; ++scope) for (scope = symbol_scope; *scope; ++scope)
if (do_lookup (undef_name, hash, *ref, &current_value, if (do_lookup (undef_name, undef_map, hash, *ref, &current_value,
*scope, 0, reference_name, NULL, reloc_type)) *scope, 0, NULL, reloc_type))
break; break;
if (current_value.s == NULL) if (current_value.s == NULL)
@ -125,11 +125,12 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
SKIP_MAP is only skipped. */ SKIP_MAP is only skipped. */
ElfW(Addr) ElfW(Addr)
internal_function internal_function
_dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref, _dl_lookup_symbol_skip (const char *undef_name,
struct link_map *undef_map, const ElfW(Sym) **ref,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
struct link_map *skip_map) struct link_map *skip_map)
{ {
const char *reference_name = undef_map ? undef_map->l_name : NULL;
const unsigned long int hash = _dl_elf_hash (undef_name); const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { NULL, NULL }; struct sym_val current_value = { NULL, NULL };
struct r_scope_elem **scope; struct r_scope_elem **scope;
@ -143,11 +144,11 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
assert (i < (*scope)->r_nduplist); assert (i < (*scope)->r_nduplist);
if (i >= (*scope)->r_nlist if (i >= (*scope)->r_nlist
|| ! do_lookup (undef_name, hash, *ref, &current_value, || ! do_lookup (undef_name, undef_map, hash, *ref, &current_value,
*scope, i, reference_name, skip_map, 0)) *scope, i, skip_map, 0))
while (*++scope) while (*++scope)
if (do_lookup (undef_name, hash, *ref, &current_value, if (do_lookup (undef_name, undef_map, hash, *ref, &current_value,
*scope, 0, reference_name, skip_map, 0)) *scope, 0, skip_map, 0))
break; break;
if (current_value.s == NULL) if (current_value.s == NULL)
@ -177,12 +178,13 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
XXX We'll see whether we need this separate function. */ XXX We'll see whether we need this separate function. */
ElfW(Addr) ElfW(Addr)
internal_function internal_function
_dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref, _dl_lookup_versioned_symbol (const char *undef_name,
struct link_map *undef_map, const ElfW(Sym) **ref,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
const struct r_found_version *version, const struct r_found_version *version,
int reloc_type) int reloc_type)
{ {
const char *reference_name = undef_map ? undef_map->l_name : NULL;
const unsigned long int hash = _dl_elf_hash (undef_name); const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { NULL, NULL }; struct sym_val current_value = { NULL, NULL };
struct r_scope_elem **scope; struct r_scope_elem **scope;
@ -192,8 +194,8 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
/* Search the relevant loaded objects for a definition. */ /* Search the relevant loaded objects for a definition. */
for (scope = symbol_scope; *scope; ++scope) for (scope = symbol_scope; *scope; ++scope)
{ {
int res = do_lookup_versioned (undef_name, hash, *ref, &current_value, int res = do_lookup_versioned (undef_name, undef_map, hash, *ref,
*scope, 0, reference_name, version, NULL, &current_value, *scope, 0, version, NULL,
reloc_type); reloc_type);
if (res > 0) if (res > 0)
break; break;
@ -250,12 +252,13 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
ElfW(Addr) ElfW(Addr)
internal_function internal_function
_dl_lookup_versioned_symbol_skip (const char *undef_name, _dl_lookup_versioned_symbol_skip (const char *undef_name,
struct link_map *undef_map,
const ElfW(Sym) **ref, const ElfW(Sym) **ref,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
const struct r_found_version *version, const struct r_found_version *version,
struct link_map *skip_map) struct link_map *skip_map)
{ {
const char *reference_name = undef_map ? undef_map->l_name : NULL;
const unsigned long int hash = _dl_elf_hash (undef_name); const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { NULL, NULL }; struct sym_val current_value = { NULL, NULL };
struct r_scope_elem **scope; struct r_scope_elem **scope;
@ -269,11 +272,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
assert (i < (*scope)->r_nduplist); assert (i < (*scope)->r_nduplist);
if (i >= (*scope)->r_nlist if (i >= (*scope)->r_nlist
|| ! do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope, || ! do_lookup_versioned (undef_name, undef_map, hash, *ref,
i, reference_name, version, skip_map, 0)) &current_value, *scope, i, version, skip_map,
0))
while (*++scope) while (*++scope)
if (do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope, if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
0, reference_name, version, skip_map, 0)) &current_value, *scope, 0, version, skip_map,
0))
break; break;
if (current_value.s == NULL) if (current_value.s == NULL)

View File

@ -20,9 +20,10 @@
#include <assert.h> #include <assert.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <libintl.h> #include <unistd.h>
#include <sys/mman.h> /* Check whether MAP_COPY is defined. */ #include <sys/mman.h> /* Check whether MAP_COPY is defined. */
#include <sys/param.h> #include <sys/param.h>
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
@ -100,6 +101,12 @@ dl_open_worker (void *a)
struct link_map *call_map; struct link_map *call_map;
char *new_file; char *new_file;
/* DSTs must not appear in SUID/SGID programs. */
if (__libc_enable_secure)
/* This is an error. */
_dl_signal_error (0, "dlopen",
"DST not allowed in SUID/SGID programs");
/* We have to find out from which object the caller is calling. /* We have to find out from which object the caller is calling.
Find the highest-addressed object that ADDRESS is not below. */ Find the highest-addressed object that ADDRESS is not below. */
call_map = NULL; call_map = NULL;

View File

@ -71,11 +71,13 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE(ref, version, flags) \ #define RESOLVE(ref, version, flags) \
((version) != NULL && (version)->hash != 0 \ (ELFW(ST_VISIBILITY) ((*ref)->st_other) != STV_PROTECTED \
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \ ? ((version) != NULL && (version)->hash != 0 \
l->l_name, (version), (flags)) \ ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \ scope, (version), (flags)) \
l->l_name, (flags))) : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope, \
(flags))) \
: l->l_addr)
#include "dynamic-link.h" #include "dynamic-link.h"
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
@ -96,6 +98,9 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
/* Mark the object so we know this work has been done. */ /* Mark the object so we know this work has been done. */
l->l_relocated = 1; l->l_relocated = 1;
/* DT_TEXTREL is now in level 2 and might phase out at some time.
But we rewrite the DT_FLAGS entry to make testing easier and
therefore it will be available at all time. */
if (l->l_info[DT_TEXTREL]) if (l->l_info[DT_TEXTREL])
{ {
/* Undo the protection change we made before relocating. */ /* Undo the protection change we made before relocating. */

View File

@ -66,32 +66,40 @@ fixup (
/* Sanity check that we're really looking at a PLT relocation. */ /* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
/* Look up the target symbol. */ /* Look up the target symbol. If the symbol is marked STV_PROTEXTED
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) don't look in the global scope. */
if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
{ {
default: switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{ {
const ElfW(Half) *vernum = default:
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];
if (version->hash != 0)
{ {
value = _dl_lookup_versioned_symbol(strtab + sym->st_name, const ElfW(Half) *vernum =
&sym, l->l_scope, l->l_name, (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
version, ELF_MACHINE_JMP_SLOT); ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
break; const struct r_found_version *version = &l->l_versions[ndx];
}
}
case 0:
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
l->l_name, ELF_MACHINE_JMP_SLOT);
}
/* Currently value contains the base load address of the object if (version->hash != 0)
that defines sym. Now add in the symbol offset. */ {
value = (sym ? value + sym->st_value : 0); value = _dl_lookup_versioned_symbol(strtab + sym->st_name, l,
&sym, l->l_scope, version,
ELF_MACHINE_JMP_SLOT);
break;
}
}
case 0:
value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
l->l_scope, ELF_MACHINE_JMP_SLOT);
}
/* Currently value contains the base load address of the object
that defines sym. Now add in the symbol offset. */
value = (sym ? value + sym->st_value : 0);
}
else
/* We already found the symbol. The module (and therefore its load
address) is also known. */
value = l->l_addr + sym->st_value;
/* And now perhaps the relocation addend. */ /* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value); value = elf_machine_plt_value (l, reloc, value);
@ -141,33 +149,41 @@ profile_fixup (
/* Sanity check that we're really looking at a PLT relocation. */ /* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
/* Look up the target symbol. */ /* Look up the target symbol. If the symbol is marked STV_PROTEXTED
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) don't look in the global scope. */
if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
{ {
default: switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{ {
const ElfW(Half) *vernum = default:
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];
if (version->hash != 0)
{ {
value = _dl_lookup_versioned_symbol(strtab + sym->st_name, const ElfW(Half) *vernum =
&sym, l->l_scope, (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
l->l_name, version, ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
ELF_MACHINE_JMP_SLOT); const struct r_found_version *version = &l->l_versions[ndx];
break;
}
}
case 0:
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
l->l_name, ELF_MACHINE_JMP_SLOT);
}
/* Currently value contains the base load address of the object if (version->hash != 0)
that defines sym. Now add in the symbol offset. */ {
value = (sym ? value + sym->st_value : 0); value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
l, &sym, l->l_scope,
version,
ELF_MACHINE_JMP_SLOT);
break;
}
}
case 0:
value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
l->l_scope, ELF_MACHINE_JMP_SLOT);
}
/* Currently value contains the base load address of the object
that defines sym. Now add in the symbol offset. */
value = (sym ? value + sym->st_value : 0);
}
else
/* We already found the symbol. The module (and therefore its load
address) is also known. */
value = l->l_addr + sym->st_value;
/* And now perhaps the relocation addend. */ /* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value); value = elf_machine_plt_value (l, reloc, value);

View File

@ -34,7 +34,7 @@ _dl_sym (void *handle, const char *name, void *who)
if (handle == RTLD_DEFAULT) if (handle == RTLD_DEFAULT)
/* Search the global scope. */ /* Search the global scope. */
loadbase = _dl_lookup_symbol (name, &ref, _dl_global_scope, NULL, 0); loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
else if (handle == RTLD_NEXT) else if (handle == RTLD_NEXT)
{ {
struct link_map *l, *match; struct link_map *l, *match;
@ -54,15 +54,14 @@ RTLD_NEXT used in code not dynamically loaded"));
while (l->l_loader) while (l->l_loader)
l = l->l_loader; l = l->l_loader;
loadbase = _dl_lookup_symbol_skip (name, &ref, l->l_local_scope, loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
NULL, match); match);
} }
else else
{ {
/* Search the scope of the given object. */ /* Search the scope of the given object. */
struct link_map *map = handle; struct link_map *map = handle;
loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
map->l_name, 0);
} }
if (loadbase) if (loadbase)
@ -88,8 +87,8 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
if (handle == RTLD_DEFAULT) if (handle == RTLD_DEFAULT)
/* Search the global scope. */ /* Search the global scope. */
loadbase = _dl_lookup_versioned_symbol (name, &ref, _dl_global_scope, loadbase = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope,
NULL, &vers, 0); &vers, 0);
else if (handle == RTLD_NEXT) else if (handle == RTLD_NEXT)
{ {
struct link_map *l, *match; struct link_map *l, *match;
@ -109,17 +108,16 @@ RTLD_NEXT used in code not dynamically loaded"));
while (l->l_loader) while (l->l_loader)
l = l->l_loader; l = l->l_loader;
loadbase = _dl_lookup_versioned_symbol_skip (name, &ref, loadbase = _dl_lookup_versioned_symbol_skip (name, l, &ref,
l->l_local_scope, l->l_local_scope,
NULL, &vers, match); &vers, match);
} }
else else
{ {
/* Search the scope of the given object. */ /* Search the scope of the given object. */
struct link_map *map = handle; struct link_map *map = handle;
loadbase = _dl_lookup_versioned_symbol (name, &ref, loadbase = _dl_lookup_versioned_symbol (name, map, &ref,
map->l_local_scope, map->l_local_scope, &vers, 0);
map->l_name, &vers, 0);
} }
if (loadbase) if (loadbase)

View File

@ -1,5 +1,5 @@
/* Look up a symbol's run-time value in the scope of a loaded object. /* Look up a symbol's run-time value in the scope of a loaded object.
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -28,7 +28,6 @@ _dl_symbol_value (struct link_map *map, const char *name)
{ {
ElfW(Addr) loadbase; ElfW(Addr) loadbase;
const ElfW(Sym) *ref = NULL; const ElfW(Sym) *ref = NULL;
loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, map->l_name, loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
0);
return loadbase + ref->st_value; return loadbase + ref->st_value;
} }

View File

@ -29,10 +29,10 @@
found the symbol, the value 0 if nothing is found and < 0 if found the symbol, the value 0 if nothing is found and < 0 if
something bad happened. */ something bad happened. */
static inline int static inline int
FCT (const char *undef_name, unsigned long int hash, FCT (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) *ref, struct sym_val *result, unsigned long int hash, const ElfW(Sym) *ref, struct sym_val *result,
struct r_scope_elem *scope, size_t i, const char *reference_name, struct r_scope_elem *scope, size_t i, ARG struct link_map *skip,
ARG struct link_map *skip, int reloc_type) int reloc_type)
{ {
struct link_map **list = scope->r_list; struct link_map **list = scope->r_list;
size_t n = scope->r_nlist; size_t n = scope->r_nlist;
@ -154,7 +154,12 @@ FCT (const char *undef_name, unsigned long int hash,
sym = num_versions == 1 ? versioned_sym : NULL; sym = num_versions == 1 ? versioned_sym : NULL;
#endif #endif
if (sym != NULL) if (sym != NULL
/* Don't allow binding if the symbol is hidden. When processor
specific definitions for STV_INTERNAL are defined we might
have to extend this conditional. */
&& (ELFW(ST_VISIBILITY) (sym->st_other) != STV_HIDDEN
|| map == undef_map))
{ {
found_it: found_it:
switch (ELFW(ST_BIND) (sym->st_info)) switch (ELFW(ST_BIND) (sym->st_info))

View File

@ -93,6 +93,19 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
info[DT_JMPREL]->d_un.d_ptr += l_addr; info[DT_JMPREL]->d_un.d_ptr += l_addr;
if (info[VERSYMIDX (DT_VERSYM)] != NULL) if (info[VERSYMIDX (DT_VERSYM)] != NULL)
info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr; info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
if (info[DT_FLAGS] != NULL)
{
/* Flags are used. Translate to the old form where available.
Since these l_info entries are only tested for NULL pointers it
is ok if they point to the DT_FLAGS entry. */
ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val;
if (flags & DF_SYMBOLIC)
info[DT_SYMBOLIC] = info[DT_FLAGS];
if (flags & DF_TEXTREL)
info[DT_TEXTREL] = info[DT_FLAGS];
if (flags & DF_BIND_NOW)
info[DT_BIND_NOW] = info[DT_FLAGS];
}
} }
#ifdef RESOLVE #ifdef RESOLVE

View File

@ -260,35 +260,35 @@ extern void _dl_setup_hash (struct link_map *map) internal_function;
the `elf_machine_lookup_*_p' macros in dl-machine.h to affect which the `elf_machine_lookup_*_p' macros in dl-machine.h to affect which
symbols can be chosen. */ symbols can be chosen. */
extern ElfW(Addr) _dl_lookup_symbol (const char *undef, extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
struct link_map *undef_map,
const ElfW(Sym) **sym, const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
int reloc_type) int reloc_type)
internal_function; internal_function;
/* Lookup versioned symbol. */ /* Lookup versioned symbol. */
extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef, extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef,
struct link_map *undef_map,
const ElfW(Sym) **sym, const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
const struct r_found_version *version, const struct r_found_version *version,
int reloc_type) int reloc_type)
internal_function; internal_function;
/* For handling RTLD_NEXT we must be able to skip shared objects. */ /* For handling RTLD_NEXT we must be able to skip shared objects. */
extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef, extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef,
struct link_map *undef_map,
const ElfW(Sym) **sym, const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
struct link_map *skip_this) struct link_map *skip_this)
internal_function; internal_function;
/* For handling RTLD_NEXT with versioned symbols we must be able to /* For handling RTLD_NEXT with versioned symbols we must be able to
skip shared objects. */ skip shared objects. */
extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef, extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
struct link_map *undef_map,
const ElfW(Sym) **sym, const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[], struct r_scope_elem *symbol_scope[],
const char *reference_name,
const struct r_found_version *version, const struct r_found_version *version,
struct link_map *skip_this) struct link_map *skip_this)
internal_function; internal_function;

View File

@ -63,4 +63,13 @@ extern int __profil __P ((unsigned short int *__sample_buffer, size_t __size,
size_t __offset, unsigned int __scale)); size_t __offset, unsigned int __scale));
extern int __getdtablesize __P ((void)); extern int __getdtablesize __P ((void));
extern int __brk __P ((__ptr_t __addr)); extern int __brk __P ((__ptr_t __addr));
/* This variable is set nonzero at startup if the process's effective
IDs differ from its real IDs, or it is otherwise indicated that
extra security should be used. When this is set the dynamic linker
and some functions contained in the C library ignore various
environment variables that normally affect them. */
extern int __libc_enable_secure;
#endif #endif

View File

@ -927,16 +927,7 @@ extern int lockf64 __P ((int __fd, int __cmd, __off64_t __len));
({ long int __result; \ ({ long int __result; \
do __result = (long int) (expression); \ do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \ while (__result == -1L && errno == EINTR); \
__result; })) \ __result; }))
/* This variable is set nonzero at startup if the process's effective
IDs differ from its real IDs, or it is otherwise indicated that
extra security should be used. When this is set the dynamic linker
and some functions contained in the C library ignore various
environment variables that normally affect them. */
extern int __libc_enable_secure;
#endif #endif
#if defined __USE_POSIX199309 || defined __USE_UNIX98 #if defined __USE_POSIX199309 || defined __USE_UNIX98