diff options
Diffstat (limited to 'meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch')
-rw-r--r-- | meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch b/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch new file mode 100644 index 0000000000..a87afe3230 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch | |||
@@ -0,0 +1,180 @@ | |||
1 | From ba33937be210da5d07f7f01709323743f66011ce Mon Sep 17 00:00:00 2001 | ||
2 | From: Adhemerval Zanella <adhemerval.zanella@linaro.org> | ||
3 | Date: Fri, 25 Jun 2021 10:54:12 -0300 | ||
4 | Subject: [PATCH] elf: Fix DTV gap reuse logic (BZ #27135) | ||
5 | |||
6 | This is updated version of the 572bd547d57a (reverted by 40ebfd016ad2) | ||
7 | that fixes the _dl_next_tls_modid issues. | ||
8 | |||
9 | This issue with 572bd547d57a patch is the DTV entry will be only | ||
10 | update on dl_open_worker() with the update_tls_slotinfo() call after | ||
11 | all dependencies are being processed by _dl_map_object_deps(). However | ||
12 | _dl_map_object_deps() itself might call _dl_next_tls_modid(), and since | ||
13 | the _dl_tls_dtv_slotinfo_list::map is not yet set the entry will be | ||
14 | wrongly reused. | ||
15 | |||
16 | This patch fixes by renaming the _dl_next_tls_modid() function to | ||
17 | _dl_assign_tls_modid() and by passing the link_map so it can set | ||
18 | the slotinfo value so a subsequente _dl_next_tls_modid() call will | ||
19 | see the entry as allocated. | ||
20 | |||
21 | The intermediary value is cleared up on remove_slotinfo() for the case | ||
22 | a library fails to load with RTLD_NOW. | ||
23 | |||
24 | This patch fixes BZ #27135. | ||
25 | |||
26 | Checked on x86_64-linux-gnu. | ||
27 | |||
28 | Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com> | ||
29 | --- | ||
30 | elf/dl-close.c | 8 +- | ||
31 | elf/dl-load.c | 2 +- | ||
32 | elf/dl-open.c | 10 -- | ||
33 | elf/dl-tls.c | 17 +-- | ||
34 | elf/rtld.c | 2 +- | ||
35 | sysdeps/generic/ldsodefs.h | 4 +- | ||
36 | 6 files changed, 349 insertions(+), 33 deletions(-) | ||
37 | --- | ||
38 | Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=ba33937be210da5d07f7f01709323743f66011ce] | ||
39 | Comment: Removed hunks those were related to test. Hunk from elf/rtld.c is refreshed. | ||
40 | Signed-off-by: Akash Hadke <akash.hadke@kpit.com> | ||
41 | Signed-off-by: Akash Hadke <hadkeakash4@gmail.com> | ||
42 | --- | ||
43 | diff --git a/elf/dl-close.c b/elf/dl-close.c | ||
44 | index 3720e47dd1..f39001cab9 100644 | ||
45 | --- a/elf/dl-close.c | ||
46 | +++ b/elf/dl-close.c | ||
47 | @@ -77,8 +77,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, | ||
48 | object that wasn't fully set up. */ | ||
49 | if (__glibc_likely (old_map != NULL)) | ||
50 | { | ||
51 | - assert (old_map->l_tls_modid == idx); | ||
52 | - | ||
53 | /* Mark the entry as unused. These can be read concurrently. */ | ||
54 | atomic_store_relaxed (&listp->slotinfo[idx - disp].gen, | ||
55 | GL(dl_tls_generation) + 1); | ||
56 | @@ -88,7 +86,11 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, | ||
57 | /* If this is not the last currently used entry no need to look | ||
58 | further. */ | ||
59 | if (idx != GL(dl_tls_max_dtv_idx)) | ||
60 | - return true; | ||
61 | + { | ||
62 | + /* There is an unused dtv entry in the middle. */ | ||
63 | + GL(dl_tls_dtv_gaps) = true; | ||
64 | + return true; | ||
65 | + } | ||
66 | } | ||
67 | |||
68 | while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0)) | ||
69 | diff --git a/elf/dl-load.c b/elf/dl-load.c | ||
70 | index a08df001af..650e4edc35 100644 | ||
71 | --- a/elf/dl-load.c | ||
72 | +++ b/elf/dl-load.c | ||
73 | @@ -1498,7 +1498,7 @@ cannot enable executable stack as shared object requires"); | ||
74 | not set up TLS data structures, so don't use them now. */ | ||
75 | || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL))) | ||
76 | /* Assign the next available module ID. */ | ||
77 | - l->l_tls_modid = _dl_next_tls_modid (); | ||
78 | + _dl_assign_tls_modid (l); | ||
79 | |||
80 | #ifdef DL_AFTER_LOAD | ||
81 | DL_AFTER_LOAD (l); | ||
82 | diff --git a/elf/dl-open.c b/elf/dl-open.c | ||
83 | index a066f39bd0..d2240d8747 100644 | ||
84 | --- a/elf/dl-open.c | ||
85 | +++ b/elf/dl-open.c | ||
86 | @@ -899,16 +899,6 @@ no more namespaces available for dlmopen()")); | ||
87 | state if relocation failed, for example. */ | ||
88 | if (args.map) | ||
89 | { | ||
90 | - /* Maybe some of the modules which were loaded use TLS. | ||
91 | - Since it will be removed in the following _dl_close call | ||
92 | - we have to mark the dtv array as having gaps to fill the | ||
93 | - holes. This is a pessimistic assumption which won't hurt | ||
94 | - if not true. There is no need to do this when we are | ||
95 | - loading the auditing DSOs since TLS has not yet been set | ||
96 | - up. */ | ||
97 | - if ((mode & __RTLD_AUDIT) == 0) | ||
98 | - GL(dl_tls_dtv_gaps) = true; | ||
99 | - | ||
100 | _dl_close_worker (args.map, true); | ||
101 | |||
102 | /* All l_nodelete_pending objects should have been deleted | ||
103 | diff --git a/elf/dl-tls.c b/elf/dl-tls.c | ||
104 | index 2b5161d10a..423e380f7c 100644 | ||
105 | --- a/elf/dl-tls.c | ||
106 | +++ b/elf/dl-tls.c | ||
107 | @@ -126,8 +126,8 @@ oom (void) | ||
108 | } | ||
109 | |||
110 | |||
111 | -size_t | ||
112 | -_dl_next_tls_modid (void) | ||
113 | +void | ||
114 | +_dl_assign_tls_modid (struct link_map *l) | ||
115 | { | ||
116 | size_t result; | ||
117 | |||
118 | @@ -157,7 +157,11 @@ _dl_next_tls_modid (void) | ||
119 | } | ||
120 | |||
121 | if (result - disp < runp->len) | ||
122 | - break; | ||
123 | + { | ||
124 | + /* Mark the entry as used, so any dependency see it. */ | ||
125 | + atomic_store_relaxed (&runp->slotinfo[result - disp].map, l); | ||
126 | + break; | ||
127 | + } | ||
128 | |||
129 | disp += runp->len; | ||
130 | } | ||
131 | @@ -184,17 +188,14 @@ _dl_next_tls_modid (void) | ||
132 | atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), result); | ||
133 | } | ||
134 | |||
135 | - return result; | ||
136 | + l->l_tls_modid = result; | ||
137 | } | ||
138 | |||
139 | |||
140 | size_t | ||
141 | _dl_count_modids (void) | ||
142 | { | ||
143 | - /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where | ||
144 | - we fail to load a module and unload it leaving a gap. If we don't | ||
145 | - have gaps then the number of modids is the current maximum so | ||
146 | - return that. */ | ||
147 | + /* The count is the max unless dlclose or failed dlopen created gaps. */ | ||
148 | if (__glibc_likely (!GL(dl_tls_dtv_gaps))) | ||
149 | return GL(dl_tls_max_dtv_idx); | ||
150 | |||
151 | diff --git a/elf/rtld.c b/elf/rtld.c | ||
152 | index e3fb2a5b2a..d733359eaf 100644 | ||
153 | --- a/elf/rtld.c | ||
154 | +++ b/elf/rtld.c | ||
155 | @@ -1612,7 +1612,7 @@ | ||
156 | /* Add the dynamic linker to the TLS list if it also uses TLS. */ | ||
157 | if (GL(dl_rtld_map).l_tls_blocksize != 0) | ||
158 | /* Assign a module ID. Do this before loading any audit modules. */ | ||
159 | - GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); | ||
160 | + _dl_assign_tls_modid (&GL(dl_rtld_map)); | ||
161 | |||
162 | /* If we have auditing DSOs to load, do it now. */ | ||
163 | bool need_security_init = true; | ||
164 | diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h | ||
165 | index 176394de4d..9c15259236 100644 | ||
166 | --- a/sysdeps/generic/ldsodefs.h | ||
167 | +++ b/sysdeps/generic/ldsodefs.h | ||
168 | @@ -1171,8 +1171,8 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, | ||
169 | extern void _dl_sysdep_start_cleanup (void) attribute_hidden; | ||
170 | |||
171 | |||
172 | -/* Determine next available module ID. */ | ||
173 | -extern size_t _dl_next_tls_modid (void) attribute_hidden; | ||
174 | +/* Determine next available module ID and set the L l_tls_modid. */ | ||
175 | +extern void _dl_assign_tls_modid (struct link_map *l) attribute_hidden; | ||
176 | |||
177 | /* Count the modules with TLS segments. */ | ||
178 | extern size_t _dl_count_modids (void) attribute_hidden; | ||
179 | -- | ||
180 | 2.27.0 | ||