]>
Commit | Line | Data |
---|---|---|
12788f63 MT |
1 | 2011-02-23 Andreas Schwab <schwab@redhat.com> |
2 | ||
3 | [BZ #12509] | |
4 | * elf/dl-load.c (_dl_map_object_from_fd): Free realname before | |
5 | returning unsuccessfully. | |
6 | * elf/Makefile ($(objpfx)noload-mem): New rule. | |
7 | (noload-ENV): Define. | |
8 | (tests): Add $(objpfx)noload-mem. | |
9 | * elf/noload.c: Include <memcheck.h>. | |
10 | (main): Call mtrace. Close all opened handles. | |
11 | ||
12 | 2010-09-27 Andreas Schwab <schwab@redhat.com> | |
13 | ||
14 | * include/link.h (struct link_map): Add l_free_initfini. | |
15 | * elf/dl-deps.c (_dl_map_object_deps): Set it when assigning | |
16 | l_initfini. | |
17 | * elf/rtld.c (dl_main): Clear it on all objects loaded on startup. | |
18 | * elf/dl-libc.c (free_mem): Free l_initfini if l_free_initfini is | |
19 | set. | |
20 | ||
21 | Index: glibc-2.12-2-gc4ccff1/elf/Makefile | |
22 | =================================================================== | |
23 | --- glibc-2.12-2-gc4ccff1.orig/elf/Makefile | |
24 | +++ glibc-2.12-2-gc4ccff1/elf/Makefile | |
25 | @@ -211,7 +211,7 @@ endif | |
26 | ifeq (yesyes,$(have-fpie)$(build-shared)) | |
27 | tests: $(objpfx)tst-pie1.out | |
28 | endif | |
29 | -tests: $(objpfx)tst-leaks1-mem | |
30 | +tests: $(objpfx)tst-leaks1-mem $(objpfx)noload-mem | |
31 | tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
32 | tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
33 | modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ | |
34 | @@ -664,6 +664,10 @@ $(objpfx)noload: $(objpfx)testobj1.so $( | |
35 | LDFLAGS-noload = -rdynamic | |
36 | $(objpfx)noload.out: $(objpfx)testobj5.so | |
37 | ||
38 | +$(objpfx)noload-mem: $(objpfx)noload.out | |
39 | + $(common-objpfx)malloc/mtrace $(objpfx)noload.mtrace > $@ | |
40 | +noload-ENV = MALLOC_TRACE=$(objpfx)noload.mtrace | |
41 | + | |
42 | LDFLAGS-nodelete = -rdynamic | |
43 | LDFLAGS-nodelmod1.so = -Wl,--enable-new-dtags,-z,nodelete | |
44 | LDFLAGS-nodelmod4.so = -Wl,--enable-new-dtags,-z,nodelete | |
45 | Index: glibc-2.12-2-gc4ccff1/elf/dl-deps.c | |
46 | =================================================================== | |
47 | --- glibc-2.12-2-gc4ccff1.orig/elf/dl-deps.c | |
48 | +++ glibc-2.12-2-gc4ccff1/elf/dl-deps.c | |
49 | @@ -478,6 +478,7 @@ _dl_map_object_deps (struct link_map *ma | |
50 | nneeded * sizeof needed[0]); | |
51 | atomic_write_barrier (); | |
52 | l->l_initfini = l_initfini; | |
53 | + l->l_free_initfini = 1; | |
54 | } | |
55 | ||
56 | /* If we have no auxiliary objects just go on to the next map. */ | |
57 | @@ -662,6 +663,7 @@ Filters not supported with LD_TRACE_PREL | |
58 | l_initfini[nlist] = NULL; | |
59 | atomic_write_barrier (); | |
60 | map->l_initfini = l_initfini; | |
61 | + map->l_free_initfini = 1; | |
62 | if (l_reldeps != NULL) | |
63 | { | |
64 | atomic_write_barrier (); | |
65 | Index: glibc-2.12-2-gc4ccff1/elf/dl-libc.c | |
66 | =================================================================== | |
67 | --- glibc-2.12-2-gc4ccff1.orig/elf/dl-libc.c | |
68 | +++ glibc-2.12-2-gc4ccff1/elf/dl-libc.c | |
69 | @@ -250,5 +250,9 @@ libc_freeres_fn (free_mem) | |
70 | if (! old->dont_free) | |
71 | free (old); | |
72 | } | |
73 | + | |
74 | + /* Free the initfini dependency list. */ | |
75 | + if (l->l_free_initfini) | |
76 | + free (l->l_initfini); | |
77 | } | |
78 | } | |
79 | Index: glibc-2.12-2-gc4ccff1/elf/dl-load.c | |
80 | =================================================================== | |
81 | --- glibc-2.12-2-gc4ccff1.orig/elf/dl-load.c | |
82 | +++ glibc-2.12-2-gc4ccff1/elf/dl-load.c | |
83 | @@ -907,6 +907,7 @@ _dl_map_object_from_fd (const char *name | |
84 | { | |
85 | /* We are not supposed to load the object unless it is already | |
86 | loaded. So return now. */ | |
87 | + free (realname); | |
88 | __close (fd); | |
89 | return NULL; | |
90 | } | |
91 | @@ -925,6 +926,7 @@ _dl_map_object_from_fd (const char *name | |
92 | _dl_zerofd = _dl_sysdep_open_zero_fill (); | |
93 | if (_dl_zerofd == -1) | |
94 | { | |
95 | + free (realname); | |
96 | __close (fd); | |
97 | _dl_signal_error (errno, NULL, NULL, | |
98 | N_("cannot open zero fill device")); | |
99 | Index: glibc-2.12-2-gc4ccff1/elf/noload.c | |
100 | =================================================================== | |
101 | --- glibc-2.12-2-gc4ccff1.orig/elf/noload.c | |
102 | +++ glibc-2.12-2-gc4ccff1/elf/noload.c | |
103 | @@ -1,20 +1,28 @@ | |
104 | #include <dlfcn.h> | |
105 | #include <stdio.h> | |
106 | +#include <mcheck.h> | |
107 | ||
108 | int | |
109 | main (void) | |
110 | { | |
111 | int result = 0; | |
112 | + void *p; | |
113 | + | |
114 | + mtrace (); | |
115 | ||
116 | /* First try to load an object which is a dependency. This should | |
117 | succeed. */ | |
118 | - if (dlopen ("testobj1.so", RTLD_LAZY | RTLD_NOLOAD) == NULL) | |
119 | + p = dlopen ("testobj1.so", RTLD_LAZY | RTLD_NOLOAD); | |
120 | + if (p == NULL) | |
121 | { | |
122 | printf ("cannot open \"testobj1.so\": %s\n", dlerror ()); | |
123 | result = 1; | |
124 | } | |
125 | else | |
126 | - puts ("loading \"testobj1.so\" succeeded, OK"); | |
127 | + { | |
128 | + puts ("loading \"testobj1.so\" succeeded, OK"); | |
129 | + dlclose (p); | |
130 | + } | |
131 | ||
132 | /* Now try loading an object which is not already loaded. */ | |
133 | if (dlopen ("testobj5.so", RTLD_LAZY | RTLD_NOLOAD) != NULL) | |
134 | @@ -25,8 +33,6 @@ main (void) | |
135 | else | |
136 | { | |
137 | /* Load the object and run the same test again. */ | |
138 | - void *p; | |
139 | - | |
140 | puts ("\"testobj5.so\" wasn't loaded and RTLD_NOLOAD prevented it, OK"); | |
141 | ||
142 | p = dlopen ("testobj5.so", RTLD_LAZY); | |
143 | @@ -41,13 +47,17 @@ main (void) | |
144 | { | |
145 | puts ("loading \"testobj5.so\" succeeded, OK"); | |
146 | ||
147 | - if (dlopen ("testobj5.so", RTLD_LAZY | RTLD_NOLOAD) == NULL) | |
148 | + void *q = dlopen ("testobj5.so", RTLD_LAZY | RTLD_NOLOAD); | |
149 | + if (q == NULL) | |
150 | { | |
151 | printf ("cannot open \"testobj5.so\": %s\n", dlerror ()); | |
152 | result = 1; | |
153 | } | |
154 | else | |
155 | - puts ("loading \"testobj5.so\" with RTLD_NOLOAD succeeded, OK"); | |
156 | + { | |
157 | + puts ("loading \"testobj5.so\" with RTLD_NOLOAD succeeded, OK"); | |
158 | + dlclose (q); | |
159 | + } | |
160 | ||
161 | if (dlclose (p) != 0) | |
162 | { | |
163 | Index: glibc-2.12-2-gc4ccff1/elf/rtld.c | |
164 | =================================================================== | |
165 | --- glibc-2.12-2-gc4ccff1.orig/elf/rtld.c | |
166 | +++ glibc-2.12-2-gc4ccff1/elf/rtld.c | |
167 | @@ -2249,6 +2249,7 @@ ERROR: ld.so: object '%s' cannot be load | |
168 | lnp->dont_free = 1; | |
169 | lnp = lnp->next; | |
170 | } | |
171 | + l->l_free_initfini = 0; | |
172 | ||
173 | if (l != &GL(dl_rtld_map)) | |
174 | _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, | |
175 | Index: glibc-2.12-2-gc4ccff1/include/link.h | |
176 | =================================================================== | |
177 | --- glibc-2.12-2-gc4ccff1.orig/include/link.h | |
178 | +++ glibc-2.12-2-gc4ccff1/include/link.h | |
179 | @@ -192,6 +192,9 @@ struct link_map | |
180 | during LD_TRACE_PRELINKING=1 | |
181 | contains any DT_SYMBOLIC | |
182 | libraries. */ | |
183 | + unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be | |
184 | + freed, ie. not allocated with | |
185 | + the dummy malloc in ld.so. */ | |
186 | ||
187 | /* Collected information about own RPATH directories. */ | |
188 | struct r_search_path_struct l_rpath_dirs; |