summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch
diff options
context:
space:
mode:
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.patch180
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 @@
1From ba33937be210da5d07f7f01709323743f66011ce Mon Sep 17 00:00:00 2001
2From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
3Date: Fri, 25 Jun 2021 10:54:12 -0300
4Subject: [PATCH] elf: Fix DTV gap reuse logic (BZ #27135)
5
6This is updated version of the 572bd547d57a (reverted by 40ebfd016ad2)
7that fixes the _dl_next_tls_modid issues.
8
9This issue with 572bd547d57a patch is the DTV entry will be only
10update on dl_open_worker() with the update_tls_slotinfo() call after
11all dependencies are being processed by _dl_map_object_deps(). However
12_dl_map_object_deps() itself might call _dl_next_tls_modid(), and since
13the _dl_tls_dtv_slotinfo_list::map is not yet set the entry will be
14wrongly reused.
15
16This 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
18the slotinfo value so a subsequente _dl_next_tls_modid() call will
19see the entry as allocated.
20
21The intermediary value is cleared up on remove_slotinfo() for the case
22a library fails to load with RTLD_NOW.
23
24This patch fixes BZ #27135.
25
26Checked on x86_64-linux-gnu.
27
28Reviewed-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---
38Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=ba33937be210da5d07f7f01709323743f66011ce]
39Comment: Removed hunks those were related to test. Hunk from elf/rtld.c is refreshed.
40Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
41Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
42---
43diff --git a/elf/dl-close.c b/elf/dl-close.c
44index 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))
69diff --git a/elf/dl-load.c b/elf/dl-load.c
70index 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);
82diff --git a/elf/dl-open.c b/elf/dl-open.c
83index 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
103diff --git a/elf/dl-tls.c b/elf/dl-tls.c
104index 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
151diff --git a/elf/rtld.c b/elf/rtld.c
152index 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;
164diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
165index 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--
1802.27.0