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
|
Without this patch programs using alsa-lib crash (alsamixer for example).
Removed Copyright reverts
Upstream-Status: Pending
http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=675155e9
http://sourceware.org/ml/libc-alpha/2011-06/msg00006.html
many distributions are using this already
http://chakra-project.org/ccr/packages/glibc/glibc/PKGBUILD
http://mailman.archlinux.org/pipermail/arch-commits/2011-June/137142.html
http://svn.mandriva.com/cgi-bin/viewvc.cgi/packages/cooker/glibc/current/SOURCES/glibc-2.14-libdl-crash.patch?view=markup&pathrev=691343
http://repos.archlinuxppc.org/wsvn/filedetails.php?repname=packages&path=%2Fglibc%2Ftrunk%2Fglibc-2.14-libdl-crash.patch
Index: libc/elf/dl-close.c
===================================================================
--- libc.orig/elf/dl-close.c 2011-12-05 20:16:38.000000000 -0800
+++ libc/elf/dl-close.c 2011-12-05 20:17:15.863326893 -0800
@@ -119,17 +119,8 @@
if (map->l_direct_opencount > 0 || map->l_type != lt_loaded
|| dl_close_state != not_pending)
{
- if (map->l_direct_opencount == 0)
- {
- if (map->l_type == lt_loaded)
- dl_close_state = rerun;
- else if (map->l_type == lt_library)
- {
- struct link_map **oldp = map->l_initfini;
- map->l_initfini = map->l_orig_initfini;
- _dl_scope_free (oldp);
- }
- }
+ if (map->l_direct_opencount == 0 && map->l_type == lt_loaded)
+ dl_close_state = rerun;
/* There are still references to this object. Do nothing more. */
if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
Index: libc/elf/dl-deps.c
===================================================================
--- libc.orig/elf/dl-deps.c 2011-12-05 20:16:38.000000000 -0800
+++ libc/elf/dl-deps.c 2011-12-05 20:19:33.179326877 -0800
@@ -478,6 +478,7 @@
nneeded * sizeof needed[0]);
atomic_write_barrier ();
l->l_initfini = l_initfini;
+ l->l_free_initfini = 1;
}
/* If we have no auxiliary objects just go on to the next map. */
@@ -678,6 +679,7 @@
l_initfini[nlist] = NULL;
atomic_write_barrier ();
map->l_initfini = l_initfini;
+ map->l_free_initfini = 1;
if (l_reldeps != NULL)
{
atomic_write_barrier ();
@@ -686,7 +688,7 @@
_dl_scope_free (old_l_reldeps);
}
if (old_l_initfini != NULL)
- map->l_orig_initfini = old_l_initfini;
+ _dl_scope_free (old_l_initfini);
if (errno_reason)
_dl_signal_error (errno_reason == -1 ? 0 : errno_reason, objname,
Index: libc/elf/dl-libc.c
===================================================================
--- libc.orig/elf/dl-libc.c 2011-10-22 09:34:03.000000000 -0700
+++ libc/elf/dl-libc.c 2011-12-05 20:17:15.863326893 -0800
@@ -265,13 +265,13 @@
for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
{
- /* Remove all additional names added to the objects. */
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
{
struct libname_list *lnp = l->l_libname->next;
l->l_libname->next = NULL;
+ /* Remove all additional names added to the objects. */
while (lnp != NULL)
{
struct libname_list *old = lnp;
@@ -279,6 +279,10 @@
if (! old->dont_free)
free (old);
}
+
+ /* Free the initfini dependency list. */
+ if (l->l_free_initfini)
+ free (l->l_initfini);
}
if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
Index: libc/elf/rtld.c
===================================================================
--- libc.orig/elf/rtld.c 2011-10-22 09:34:03.000000000 -0700
+++ libc/elf/rtld.c 2011-12-05 20:17:15.863326893 -0800
@@ -2264,6 +2264,7 @@
lnp->dont_free = 1;
lnp = lnp->next;
}
+ l->l_free_initfini = 0;
if (l != &GL(dl_rtld_map))
_dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
Index: libc/include/link.h
===================================================================
--- libc.orig/include/link.h 2011-10-22 09:32:35.000000000 -0700
+++ libc/include/link.h 2011-12-05 20:17:15.863326893 -0800
@@ -192,6 +192,9 @@
during LD_TRACE_PRELINKING=1
contains any DT_SYMBOLIC
libraries. */
+ unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
+ freed, ie. not allocated with
+ the dummy malloc in ld.so. */
/* Collected information about own RPATH directories. */
struct r_search_path_struct l_rpath_dirs;
@@ -240,9 +243,6 @@
/* List of object in order of the init and fini calls. */
struct link_map **l_initfini;
- /* The init and fini list generated at startup, saved when the
- object is also loaded dynamically. */
- struct link_map **l_orig_initfini;
/* List of the dependencies introduced through symbol binding. */
struct link_map_reldeps
|