1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
From 2f811bf88bed4a6c0dec8778847ba441736d509d Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@redhat.com>
Date: Wed, 26 May 2010 18:28:59 +0200
Subject: [PATCH] Fix scope handling during dl_close
---
ChangeLog | 12 ++++++++++++
elf/Makefile | 10 +++++++++-
elf/dl-close.c | 7 +++++++
elf/unload8.c | 33 +++++++++++++++++++++++++++++++++
elf/unload8mod1.c | 7 +++++++
elf/unload8mod1x.c | 1 +
elf/unload8mod2.c | 7 +++++++
elf/unload8mod3.c | 27 +++++++++++++++++++++++++++
8 files changed, 103 insertions(+), 1 deletions(-)
create mode 100644 elf/unload8.c
create mode 100644 elf/unload8mod1.c
create mode 100644 elf/unload8mod1x.c
create mode 100644 elf/unload8mod2.c
create mode 100644 elf/unload8mod3.c
diff --git a/elf/Makefile b/elf/Makefile
index 59e835f..65b6deb 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -89,6 +89,7 @@ distribute := rtld-Rules \
unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \
unload6mod1.c unload6mod2.c unload6mod3.c \
unload7mod1.c unload7mod2.c \
+ unload8mod1.c unload8mod1x.c unload8mod2.c unload8mod3.c \
tst-audit1.c tst-audit2.c tst-audit3.c tst-audit4.c \
tst-auditmod1.c tst-auditmod3a.c tst-auditmod3b.c \
tst-auditmod4a.c tst-auditmod4b.c \
@@ -196,7 +197,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
- unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \
+ unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
tst-audit1 tst-audit2 \
tst-stackguard1 tst-addr1 tst-thrlock \
tst-unique1 tst-unique2
@@ -247,6 +248,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
unload6mod1 unload6mod2 unload6mod3 \
unload7mod1 unload7mod2 \
+ unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
order2mod1 order2mod2 order2mod3 order2mod4 \
tst-unique1mod1 tst-unique1mod2 \
tst-unique2mod1 tst-unique2mod2
@@ -522,6 +524,9 @@ $(objpfx)unload6mod2.so: $(libdl)
$(objpfx)unload6mod3.so: $(libdl)
$(objpfx)unload7mod1.so: $(libdl)
$(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so
+$(objpfx)unload8mod1.so: $(objpfx)unload8mod2.so
+$(objpfx)unload8mod2.so: $(objpfx)unload8mod3.so
+$(objpfx)unload8mod3.so: $(libdl)
$(objpfx)tst-initordera2.so: $(objpfx)tst-initordera1.so
$(objpfx)tst-initorderb2.so: $(objpfx)tst-initorderb1.so $(objpfx)tst-initordera2.so
$(objpfx)tst-initordera3.so: $(objpfx)tst-initorderb2.so $(objpfx)tst-initorderb1.so
@@ -823,6 +828,9 @@ $(objpfx)unload7: $(libdl)
$(objpfx)unload7.out: $(objpfx)unload7mod1.so $(objpfx)unload7mod2.so
unload7-ENV = MALLOC_PERTURB_=85
+$(objpfx)unload8: $(libdl)
+$(objpfx)unload8.out: $(objpfx)unload8mod1.so $(objpfx)unload8mod1x.so
+
ifdef libdl
$(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
$(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 700e765..f47d5f8 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -421,6 +421,13 @@ _dl_close_worker (struct link_map *map)
imap->l_scope_max = new_size;
}
+ else if (new_list != NULL)
+ {
+ /* We didn't change the scope array, so reset the search
+ list. */
+ imap->l_searchlist.r_list = NULL;
+ imap->l_searchlist.r_nlist = 0;
+ }
/* The loader is gone, so mark the object as not having one.
Note: l_idx != IDX_STILL_USED -> object will be removed. */
diff --git a/elf/unload8.c b/elf/unload8.c
new file mode 100644
index 0000000..f984a38
--- /dev/null
+++ b/elf/unload8.c
@@ -0,0 +1,33 @@
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+ void *h = dlopen ("$ORIGIN/unload8mod1.so", RTLD_LAZY);
+ if (h == NULL)
+ {
+ puts ("dlopen unload8mod1.so failed");
+ return 1;
+ }
+
+ void *h2 = dlopen ("$ORIGIN/unload8mod1x.so", RTLD_LAZY);
+ if (h2 == NULL)
+ {
+ puts ("dlopen unload8mod1x.so failed");
+ return 1;
+ }
+ dlclose (h2);
+
+ int (*mod1) (void) = dlsym (h, "mod1");
+ if (mod1 == NULL)
+ {
+ puts ("dlsym failed");
+ return 1;
+ }
+
+ mod1 ();
+ dlclose (h);
+
+ return 0;
+}
diff --git a/elf/unload8mod1.c b/elf/unload8mod1.c
new file mode 100644
index 0000000..fe7e81c
--- /dev/null
+++ b/elf/unload8mod1.c
@@ -0,0 +1,7 @@
+extern void mod2 (void);
+
+void
+mod1 (void)
+{
+ mod2 ();
+}
diff --git a/elf/unload8mod1x.c b/elf/unload8mod1x.c
new file mode 100644
index 0000000..835b634
--- /dev/null
+++ b/elf/unload8mod1x.c
@@ -0,0 +1 @@
+int mod1x;
diff --git a/elf/unload8mod2.c b/elf/unload8mod2.c
new file mode 100644
index 0000000..2fd8b67
--- /dev/null
+++ b/elf/unload8mod2.c
@@ -0,0 +1,7 @@
+extern void mod3 (void);
+
+void
+mod2 (void)
+{
+ mod3 ();
+}
diff --git a/elf/unload8mod3.c b/elf/unload8mod3.c
new file mode 100644
index 0000000..d49e22b
--- /dev/null
+++ b/elf/unload8mod3.c
@@ -0,0 +1,27 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+mod3_fini2 (void)
+{
+}
+
+void
+mod3_fini (void)
+{
+ mod3_fini2 ();
+}
+
+void
+mod3 (void)
+{
+ void *h = dlopen ("$ORIGIN/unload8mod2.so", RTLD_LAZY);
+ if (h == NULL)
+ {
+ puts ("dlopen unload8mod2.so failed");
+ exit (1);
+ }
+
+ atexit (mod3_fini);
+}
--
1.7.3.4
|