summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-07-23 22:58:50 +0000
committerUlrich Drepper <drepper@redhat.com>1999-07-23 22:58:50 +0000
commit06535ae9487708dad9048552c9c92828d998a897 (patch)
tree644ca3f36a0aca375c41e6bdded2d3904b8821e9
parentfc9cfb28c05def1bfc0edc099d8001f83654fd10 (diff)
Update.
* 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.
-rw-r--r--ChangeLog27
-rw-r--r--elf/dl-deps.c13
-rw-r--r--elf/dl-libc.c5
-rw-r--r--elf/dl-lookup.c45
-rw-r--r--elf/dl-open.c9
-rw-r--r--elf/dl-reloc.c15
-rw-r--r--elf/dl-runtime.c106
-rw-r--r--elf/dl-sym.c22
-rw-r--r--elf/dl-symbol.c5
-rw-r--r--elf/do-lookup.h15
-rw-r--r--elf/dynamic-link.h13
-rw-r--r--elf/ldsodefs.h8
-rw-r--r--include/unistd.h9
-rw-r--r--posix/unistd.h11
14 files changed, 192 insertions, 111 deletions
diff --git a/ChangeLog b/ChangeLog
index a254cc09aa..e6995d9a8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,33 @@
DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ.
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>
* elf/dl-reloc.c (_dl_reloc_bad_type): New function.
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index b981d490df..68e4921ce5 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <sys/param.h>
#include <elf/ldsodefs.h>
@@ -96,9 +97,15 @@ struct list
\
if (__cnt != 0) \
{ \
- char *__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, \
- strlen (__str), \
- __cnt)); \
+ char *__newp; \
+ \
+ /* 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); \
\
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index afb3f2d14e..784af27c3d 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -82,9 +82,8 @@ do_dlsym (void *ptr)
{
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
args->ref = NULL;
- args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
- args->map->l_local_scope,
- args->map->l_name, 0);
+ args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref,
+ args->map->l_local_scope, 0);
}
static void
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 16173c9068..4120cb1e64 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -75,11 +75,11 @@ unsigned long int _dl_num_relocations;
ElfW(Addr)
internal_function
-_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
- struct r_scope_elem *symbol_scope[],
- const char *reference_name,
+_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
+ const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
int reloc_type)
{
+ const char *reference_name = undef_map ? undef_map->l_name : NULL;
const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { NULL, NULL };
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. */
for (scope = symbol_scope; *scope; ++scope)
- if (do_lookup (undef_name, hash, *ref, &current_value,
- *scope, 0, reference_name, NULL, reloc_type))
+ if (do_lookup (undef_name, undef_map, hash, *ref, &current_value,
+ *scope, 0, NULL, reloc_type))
break;
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. */
ElfW(Addr)
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[],
- const char *reference_name,
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);
struct sym_val current_value = { NULL, NULL };
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);
if (i >= (*scope)->r_nlist
- || ! do_lookup (undef_name, hash, *ref, &current_value,
- *scope, i, reference_name, skip_map, 0))
+ || ! do_lookup (undef_name, undef_map, hash, *ref, &current_value,
+ *scope, i, skip_map, 0))
while (*++scope)
- if (do_lookup (undef_name, hash, *ref, &current_value,
- *scope, 0, reference_name, skip_map, 0))
+ if (do_lookup (undef_name, undef_map, hash, *ref, &current_value,
+ *scope, 0, skip_map, 0))
break;
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. */
ElfW(Addr)
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[],
- const char *reference_name,
const struct r_found_version *version,
int reloc_type)
{
+ const char *reference_name = undef_map ? undef_map->l_name : NULL;
const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { NULL, NULL };
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. */
for (scope = symbol_scope; *scope; ++scope)
{
- int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
- *scope, 0, reference_name, version, NULL,
+ int res = do_lookup_versioned (undef_name, undef_map, hash, *ref,
+ &current_value, *scope, 0, version, NULL,
reloc_type);
if (res > 0)
break;
@@ -250,12 +252,13 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
ElfW(Addr)
internal_function
_dl_lookup_versioned_symbol_skip (const char *undef_name,
+ struct link_map *undef_map,
const ElfW(Sym) **ref,
struct r_scope_elem *symbol_scope[],
- const char *reference_name,
const struct r_found_version *version,
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);
struct sym_val current_value = { NULL, NULL };
struct r_scope_elem **scope;
@@ -269,11 +272,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
assert (i < (*scope)->r_nduplist);
if (i >= (*scope)->r_nlist
- || ! do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
- i, reference_name, version, skip_map, 0))
+ || ! do_lookup_versioned (undef_name, undef_map, hash, *ref,
+ &current_value, *scope, i, version, skip_map,
+ 0))
while (*++scope)
- if (do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
- 0, reference_name, version, skip_map, 0))
+ if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
+ &current_value, *scope, 0, version, skip_map,
+ 0))
break;
if (current_value.s == NULL)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index a3cd8a05a3..097fd372c0 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -20,9 +20,10 @@
#include <assert.h>
#include <dlfcn.h>
#include <errno.h>
+#include <libintl.h>
#include <stdlib.h>
#include <string.h>
-#include <libintl.h>
+#include <unistd.h>
#include <sys/mman.h> /* Check whether MAP_COPY is defined. */
#include <sys/param.h>
#include <bits/libc-lock.h>
@@ -100,6 +101,12 @@ dl_open_worker (void *a)
struct link_map *call_map;
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.
Find the highest-addressed object that ADDRESS is not below. */
call_map = NULL;
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 0bf39a8b5e..a1c235a398 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -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. */
#define RESOLVE(ref, version, flags) \
- ((version) != NULL && (version)->hash != 0 \
- ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
- l->l_name, (version), (flags)) \
- : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
- l->l_name, (flags)))
+ (ELFW(ST_VISIBILITY) ((*ref)->st_other) != STV_PROTECTED \
+ ? ((version) != NULL && (version)->hash != 0 \
+ ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \
+ scope, (version), (flags)) \
+ : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope, \
+ (flags))) \
+ : l->l_addr)
#include "dynamic-link.h"
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. */
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])
{
/* Undo the protection change we made before relocating. */
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 9f3004ecf5..a55fbf6e4b 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -66,32 +66,40 @@ fixup (
/* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
- /* Look up the target symbol. */
- switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ /* Look up the target symbol. If the symbol is marked STV_PROTEXTED
+ don't look in the global scope. */
+ if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
{
- default:
- {
- const ElfW(Half) *vernum =
- (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)
+ switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ {
+ default:
{
- value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
- &sym, l->l_scope, l->l_name,
- version, ELF_MACHINE_JMP_SLOT);
- break;
+ const ElfW(Half) *vernum =
+ (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, l,
+ &sym, l->l_scope, version,
+ ELF_MACHINE_JMP_SLOT);
+ break;
+ }
}
- }
- case 0:
- value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
- l->l_name, ELF_MACHINE_JMP_SLOT);
- }
+ 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);
+ /* 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. */
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. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
- /* Look up the target symbol. */
- switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ /* Look up the target symbol. If the symbol is marked STV_PROTEXTED
+ don't look in the global scope. */
+ if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
{
- default:
- {
- const ElfW(Half) *vernum =
- (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)
+ switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ {
+ default:
{
- value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
- &sym, l->l_scope,
- l->l_name, version,
- ELF_MACHINE_JMP_SLOT);
- break;
+ const ElfW(Half) *vernum =
+ (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,
+ l, &sym, l->l_scope,
+ version,
+ ELF_MACHINE_JMP_SLOT);
+ break;
+ }
}
- }
- case 0:
- value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
- l->l_name, ELF_MACHINE_JMP_SLOT);
+ 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);
}
-
- /* 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. */
value = elf_machine_plt_value (l, reloc, value);
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 441b54fe45..91ca1277df 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -34,7 +34,7 @@ _dl_sym (void *handle, const char *name, void *who)
if (handle == RTLD_DEFAULT)
/* 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)
{
struct link_map *l, *match;
@@ -54,15 +54,14 @@ RTLD_NEXT used in code not dynamically loaded"));
while (l->l_loader)
l = l->l_loader;
- loadbase = _dl_lookup_symbol_skip (name, &ref, l->l_local_scope,
- NULL, match);
+ loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
+ match);
}
else
{
/* Search the scope of the given object. */
struct link_map *map = handle;
- loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope,
- map->l_name, 0);
+ loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
}
if (loadbase)
@@ -88,8 +87,8 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
if (handle == RTLD_DEFAULT)
/* Search the global scope. */
- loadbase = _dl_lookup_versioned_symbol (name, &ref, _dl_global_scope,
- NULL, &vers, 0);
+ loadbase = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope,
+ &vers, 0);
else if (handle == RTLD_NEXT)
{
struct link_map *l, *match;
@@ -109,17 +108,16 @@ RTLD_NEXT used in code not dynamically loaded"));
while (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,
- NULL, &vers, match);
+ &vers, match);
}
else
{
/* Search the scope of the given object. */
struct link_map *map = handle;
- loadbase = _dl_lookup_versioned_symbol (name, &ref,
- map->l_local_scope,
- map->l_name, &vers, 0);
+ loadbase = _dl_lookup_versioned_symbol (name, map, &ref,
+ map->l_local_scope, &vers, 0);
}
if (loadbase)
diff --git a/elf/dl-symbol.c b/elf/dl-symbol.c
index 3ae44d6bea..945f5446ae 100644
--- a/elf/dl-symbol.c
+++ b/elf/dl-symbol.c
@@ -1,5 +1,5 @@
/* 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.
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;
const ElfW(Sym) *ref = NULL;
- loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, map->l_name,
- 0);
+ loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
return loadbase + ref->st_value;
}
diff --git a/elf/do-lookup.h b/elf/do-lookup.h
index 147560bd32..f83b13ccf3 100644
--- a/elf/do-lookup.h
+++ b/elf/do-lookup.h
@@ -29,10 +29,10 @@
found the symbol, the value 0 if nothing is found and < 0 if
something bad happened. */
static inline int
-FCT (const char *undef_name, unsigned long int hash,
- const ElfW(Sym) *ref, struct sym_val *result,
- struct r_scope_elem *scope, size_t i, const char *reference_name,
- ARG struct link_map *skip, int reloc_type)
+FCT (const char *undef_name, struct link_map *undef_map,
+ unsigned long int hash, const ElfW(Sym) *ref, struct sym_val *result,
+ struct r_scope_elem *scope, size_t i, ARG struct link_map *skip,
+ int reloc_type)
{
struct link_map **list = scope->r_list;
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;
#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:
switch (ELFW(ST_BIND) (sym->st_info))
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index d322c1231f..59a6001069 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -93,6 +93,19 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
info[DT_JMPREL]->d_un.d_ptr += l_addr;
if (info[VERSYMIDX (DT_VERSYM)] != NULL)
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
diff --git a/elf/ldsodefs.h b/elf/ldsodefs.h
index 483e85b085..15b7cc6037 100644
--- a/elf/ldsodefs.h
+++ b/elf/ldsodefs.h
@@ -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
symbols can be chosen. */
extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
+ struct link_map *undef_map,
const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[],
- const char *reference_name,
int reloc_type)
internal_function;
/* Lookup versioned symbol. */
extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef,
+ struct link_map *undef_map,
const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[],
- const char *reference_name,
const struct r_found_version *version,
int reloc_type)
internal_function;
/* For handling RTLD_NEXT we must be able to skip shared objects. */
extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef,
+ struct link_map *undef_map,
const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[],
- const char *reference_name,
struct link_map *skip_this)
internal_function;
/* For handling RTLD_NEXT with versioned symbols we must be able to
skip shared objects. */
extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
+ struct link_map *undef_map,
const ElfW(Sym) **sym,
struct r_scope_elem *symbol_scope[],
- const char *reference_name,
const struct r_found_version *version,
struct link_map *skip_this)
internal_function;
diff --git a/include/unistd.h b/include/unistd.h
index 955637e0fb..06fa8fbd93 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -63,4 +63,13 @@ extern int __profil __P ((unsigned short int *__sample_buffer, size_t __size,
size_t __offset, unsigned int __scale));
extern int __getdtablesize __P ((void));
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
diff --git a/posix/unistd.h b/posix/unistd.h
index ea1d47b2fb..d8800b7b3b 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -927,16 +927,7 @@ extern int lockf64 __P ((int __fd, int __cmd, __off64_t __len));
({ long int __result; \
do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \
- __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;
-
+ __result; }))
#endif
#if defined __USE_POSIX199309 || defined __USE_UNIX98