Sat Oct 4 09:37:12 2008 UTC ()
lib/39649: dlsym(3) does not follow dependencies

Pull across code from FreeBSD to do a search of the passed object and it's
NEEDED objects (dependencies).

Reviewed by gimpy.


(skrll)
diff -r1.121 -r1.122 src/libexec/ld.elf_so/rtld.c
diff -r1.78 -r1.79 src/libexec/ld.elf_so/rtld.h
diff -r1.46 -r1.47 src/libexec/ld.elf_so/symbol.c

cvs diff -r1.121 -r1.122 src/libexec/ld.elf_so/rtld.c (expand / switch to unified diff)

--- src/libexec/ld.elf_so/rtld.c 2008/09/27 03:52:05 1.121
+++ src/libexec/ld.elf_so/rtld.c 2008/10/04 09:37:12 1.122
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rtld.c,v 1.121 2008/09/27 03:52:05 macallan Exp $ */ 1/* $NetBSD: rtld.c,v 1.122 2008/10/04 09:37:12 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright 1996 John D. Polstra. 4 * Copyright 1996 John D. Polstra.
5 * Copyright 1996 Matt Thomas <matt@3am-software.com> 5 * Copyright 1996 Matt Thomas <matt@3am-software.com>
6 * Copyright 2002 Charles M. Hannum <root@ihack.net> 6 * Copyright 2002 Charles M. Hannum <root@ihack.net>
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -30,27 +30,27 @@ @@ -30,27 +30,27 @@
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Dynamic linker for ELF. 36 * Dynamic linker for ELF.
37 * 37 *
38 * John Polstra <jdp@polstra.com>. 38 * John Polstra <jdp@polstra.com>.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42#ifndef lint 42#ifndef lint
43__RCSID("$NetBSD: rtld.c,v 1.121 2008/09/27 03:52:05 macallan Exp $"); 43__RCSID("$NetBSD: rtld.c,v 1.122 2008/10/04 09:37:12 skrll Exp $");
44#endif /* not lint */ 44#endif /* not lint */
45 45
46#include <err.h> 46#include <err.h>
47#include <errno.h> 47#include <errno.h>
48#include <fcntl.h> 48#include <fcntl.h>
49#include <stdarg.h> 49#include <stdarg.h>
50#include <stdio.h> 50#include <stdio.h>
51#include <stdlib.h> 51#include <stdlib.h>
52#include <string.h> 52#include <string.h>
53#include <unistd.h> 53#include <unistd.h>
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/mman.h> 55#include <sys/mman.h>
56#include <dirent.h> 56#include <dirent.h>
@@ -879,32 +879,34 @@ dlsym(void *handle, const char *name) @@ -879,32 +879,34 @@ dlsym(void *handle, const char *name)
879 abort(); 879 abort();
880 } 880 }
881 break; 881 break;
882 882
883 default: 883 default:
884 if ((obj = _rtld_dlcheck(handle)) == NULL) 884 if ((obj = _rtld_dlcheck(handle)) == NULL)
885 return NULL; 885 return NULL;
886  886
887 if (obj->mainprog) { 887 if (obj->mainprog) {
888 /* Search main program and all libraries loaded by it */ 888 /* Search main program and all libraries loaded by it */
889 def = _rtld_symlook_list(name, hash, &_rtld_list_main, 889 def = _rtld_symlook_list(name, hash, &_rtld_list_main,
890 &defobj, false); 890 &defobj, false);
891 } else { 891 } else {
892 /* 892 Needed_Entry fake;
893 * XXX - This isn't correct. The search should include 893
894 * the whole DAG rooted at the given object. 894 /* Search the object and all the libraries loaded by it. */
895 */ 895 fake.next = NULL;
896 def = _rtld_symlook_obj(name, hash, obj, false); 896 fake.obj = (Obj_Entry *)obj;
897 defobj = obj; 897 fake.name = 0;
 898 def = _rtld_symlook_needed(name, hash, &fake, &defobj,
 899 false);
898 } 900 }
899 break; 901 break;
900 } 902 }
901  903
902 if (def != NULL) { 904 if (def != NULL) {
903#ifdef __HAVE_FUNCTION_DESCRIPTORS 905#ifdef __HAVE_FUNCTION_DESCRIPTORS
904 if (ELF_ST_TYPE(def->st_info) == STT_FUNC) 906 if (ELF_ST_TYPE(def->st_info) == STT_FUNC)
905 return (void *)_rtld_function_descriptor_alloc(defobj,  907 return (void *)_rtld_function_descriptor_alloc(defobj,
906 def, 0); 908 def, 0);
907#endif /* __HAVE_FUNCTION_DESCRIPTORS */ 909#endif /* __HAVE_FUNCTION_DESCRIPTORS */
908 return defobj->relocbase + def->st_value; 910 return defobj->relocbase + def->st_value;
909 } 911 }
910  912

cvs diff -r1.78 -r1.79 src/libexec/ld.elf_so/rtld.h (expand / switch to unified diff)

--- src/libexec/ld.elf_so/rtld.h 2008/06/03 19:32:32 1.78
+++ src/libexec/ld.elf_so/rtld.h 2008/10/04 09:37:12 1.79
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rtld.h,v 1.78 2008/06/03 19:32:32 ad Exp $ */ 1/* $NetBSD: rtld.h,v 1.79 2008/10/04 09:37:12 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright 1996 John D. Polstra. 4 * Copyright 1996 John D. Polstra.
5 * Copyright 1996 Matt Thomas <matt@3am-software.com> 5 * Copyright 1996 Matt Thomas <matt@3am-software.com>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -264,26 +264,28 @@ void _rtld_setup_pltgot(const Obj_Entry  @@ -264,26 +264,28 @@ void _rtld_setup_pltgot(const Obj_Entry
264/* search.c */ 264/* search.c */
265Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int); 265Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int);
266 266
267/* symbol.c */ 267/* symbol.c */
268unsigned long _rtld_elf_hash(const char *); 268unsigned long _rtld_elf_hash(const char *);
269const Elf_Sym *_rtld_symlook_obj(const char *, unsigned long, 269const Elf_Sym *_rtld_symlook_obj(const char *, unsigned long,
270 const Obj_Entry *, bool); 270 const Obj_Entry *, bool);
271const Elf_Sym *_rtld_find_symdef(unsigned long, const Obj_Entry *, 271const Elf_Sym *_rtld_find_symdef(unsigned long, const Obj_Entry *,
272 const Obj_Entry **, bool); 272 const Obj_Entry **, bool);
273const Elf_Sym *_rtld_symlook_list(const char *, unsigned long, 273const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
274 const Objlist *, const Obj_Entry **, bool); 274 const Objlist *, const Obj_Entry **, bool);
275const Elf_Sym *_rtld_symlook_default(const char *, unsigned long, 275const Elf_Sym *_rtld_symlook_default(const char *, unsigned long,
276 const Obj_Entry *, const Obj_Entry **, bool); 276 const Obj_Entry *, const Obj_Entry **, bool);
 277const Elf_Sym *_rtld_symlook_needed(const char *, unsigned long,
 278 const Needed_Entry *, const Obj_Entry **, bool);
277 279
278/* map_object.c */ 280/* map_object.c */
279Obj_Entry *_rtld_map_object(const char *, int, const struct stat *); 281Obj_Entry *_rtld_map_object(const char *, int, const struct stat *);
280void _rtld_obj_free(Obj_Entry *); 282void _rtld_obj_free(Obj_Entry *);
281Obj_Entry *_rtld_obj_new(void); 283Obj_Entry *_rtld_obj_new(void);
282 284
283/* function descriptors */ 285/* function descriptors */
284#ifdef __HAVE_FUNCTION_DESCRIPTORS 286#ifdef __HAVE_FUNCTION_DESCRIPTORS
285Elf_Addr _rtld_function_descriptor_alloc(const Obj_Entry *,  287Elf_Addr _rtld_function_descriptor_alloc(const Obj_Entry *,
286 const Elf_Sym *, Elf_Addr); 288 const Elf_Sym *, Elf_Addr);
287const void *_rtld_function_descriptor_function(const void *); 289const void *_rtld_function_descriptor_function(const void *);
288#endif /* __HAVE_FUNCTION_DESCRIPTORS */ 290#endif /* __HAVE_FUNCTION_DESCRIPTORS */
289 291

cvs diff -r1.46 -r1.47 src/libexec/ld.elf_so/symbol.c (expand / switch to unified diff)

--- src/libexec/ld.elf_so/symbol.c 2008/07/24 04:39:25 1.46
+++ src/libexec/ld.elf_so/symbol.c 2008/10/04 09:37:12 1.47
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: symbol.c,v 1.46 2008/07/24 04:39:25 matt Exp $ */ 1/* $NetBSD: symbol.c,v 1.47 2008/10/04 09:37:12 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright 1996 John D. Polstra. 4 * Copyright 1996 John D. Polstra.
5 * Copyright 1996 Matt Thomas <matt@3am-software.com> 5 * Copyright 1996 Matt Thomas <matt@3am-software.com>
6 * Copyright 2002 Charles M. Hannum <root@ihack.net> 6 * Copyright 2002 Charles M. Hannum <root@ihack.net>
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -30,27 +30,27 @@ @@ -30,27 +30,27 @@
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Dynamic linker for ELF. 36 * Dynamic linker for ELF.
37 * 37 *
38 * John Polstra <jdp@polstra.com>. 38 * John Polstra <jdp@polstra.com>.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42#ifndef lint 42#ifndef lint
43__RCSID("$NetBSD: symbol.c,v 1.46 2008/07/24 04:39:25 matt Exp $"); 43__RCSID("$NetBSD: symbol.c,v 1.47 2008/10/04 09:37:12 skrll Exp $");
44#endif /* not lint */ 44#endif /* not lint */
45 45
46#include <err.h> 46#include <err.h>
47#include <errno.h> 47#include <errno.h>
48#include <fcntl.h> 48#include <fcntl.h>
49#include <stdarg.h> 49#include <stdarg.h>
50#include <stdio.h> 50#include <stdio.h>
51#include <stdlib.h> 51#include <stdlib.h>
52#include <string.h> 52#include <string.h>
53#include <unistd.h> 53#include <unistd.h>
54#include <sys/types.h> 54#include <sys/types.h>
55#include <sys/mman.h> 55#include <sys/mman.h>
56#include <dirent.h> 56#include <dirent.h>
@@ -126,26 +126,76 @@ _rtld_symlook_list(const char *name, uns @@ -126,26 +126,76 @@ _rtld_symlook_list(const char *name, uns
126 def = symp; 126 def = symp;
127 defobj = elm->obj; 127 defobj = elm->obj;
128 if (ELF_ST_BIND(def->st_info) != STB_WEAK) 128 if (ELF_ST_BIND(def->st_info) != STB_WEAK)
129 break; 129 break;
130 } 130 }
131 } 131 }
132 } 132 }
133 if (def != NULL) 133 if (def != NULL)
134 *defobj_out = defobj; 134 *defobj_out = defobj;
135 return def; 135 return def;
136} 136}
137 137
138/* 138/*
 139 * Search the symbol table of a shared object and all objects needed by it for
 140 * a symbol of the given name. Search order is breadth-first. Returns a pointer
 141 * to the symbol, or NULL if no definition was found.
 142 */
 143const Elf_Sym *
 144_rtld_symlook_needed(const char *name, unsigned long hash,
 145 const Needed_Entry *needed, const Obj_Entry **defobj_out, bool inplt)
 146{
 147 const Elf_Sym *def, *def_w;
 148 const Needed_Entry *n;
 149 const Obj_Entry *obj, *defobj, *defobj1;
 150
 151 def = def_w = NULL;
 152 defobj = NULL;
 153 for (n = needed; n != NULL; n = n->next) {
 154 if ((obj = n->obj) == NULL ||
 155 (def = _rtld_symlook_obj(name, hash, obj, inplt)) == NULL)
 156 continue;
 157 defobj = obj;
 158 if (ELF_ST_BIND(def->st_info) != STB_WEAK) {
 159 *defobj_out = defobj;
 160
 161 return (def);
 162 }
 163 }
 164 /*
 165 * Either the symbol definition has not been found in directly needed
 166 * objects, or the found symbol is weak.
 167 */
 168 for (n = needed; n != NULL; n = n->next) {
 169 if ((obj = n->obj) == NULL)
 170 continue;
 171 def_w = _rtld_symlook_needed(name, hash, obj->needed, &defobj1,
 172 inplt);
 173 if (def_w == NULL)
 174 continue;
 175 if (def == NULL || ELF_ST_BIND(def_w->st_info) != STB_WEAK) {
 176 def = def_w;
 177 defobj = defobj1;
 178 if (ELF_ST_BIND(def_w->st_info) != STB_WEAK)
 179 break;
 180 }
 181 }
 182 if (def != NULL)
 183 *defobj_out = defobj;
 184
 185 return def;
 186}
 187
 188/*
139 * Search the symbol table of a single shared object for a symbol of 189 * Search the symbol table of a single shared object for a symbol of
140 * the given name. Returns a pointer to the symbol, or NULL if no 190 * the given name. Returns a pointer to the symbol, or NULL if no
141 * definition was found. 191 * definition was found.
142 * 192 *
143 * The symbol's hash value is passed in for efficiency reasons; that 193 * The symbol's hash value is passed in for efficiency reasons; that
144 * eliminates many recomputations of the hash value. 194 * eliminates many recomputations of the hash value.
145 */ 195 */
146const Elf_Sym * 196const Elf_Sym *
147_rtld_symlook_obj(const char *name, unsigned long hash, 197_rtld_symlook_obj(const char *name, unsigned long hash,
148 const Obj_Entry *obj, bool in_plt) 198 const Obj_Entry *obj, bool in_plt)
149{ 199{
150 unsigned long symnum; 200 unsigned long symnum;
151 201