]>
Commit | Line | Data |
---|---|---|
a61a21ef MT |
1 | From ccdc4cba07684fe1397e1f5f134a0a827af98c04 Mon Sep 17 00:00:00 2001 |
2 | From: Hector Martin <marcan@marcan.st> | |
3 | Date: Tue, 28 Nov 2023 15:23:07 +0900 | |
4 | Subject: [PATCH 34/44] elf: Fix TLS modid reuse generation assignment (BZ | |
5 | 29039) | |
6 | ||
7 | _dl_assign_tls_modid() assigns a slotinfo entry for a new module, but | |
8 | does *not* do anything to the generation counter. The first time this | |
9 | happens, the generation is zero and map_generation() returns the current | |
10 | generation to be used during relocation processing. However, if | |
11 | a slotinfo entry is later reused, it will already have a generation | |
12 | assigned. If this generation has fallen behind the current global max | |
13 | generation, then this causes an obsolete generation to be assigned | |
14 | during relocation processing, as map_generation() returns this | |
15 | generation if nonzero. _dl_add_to_slotinfo() eventually resets the | |
16 | generation, but by then it is too late. This causes DTV updates to be | |
17 | skipped, leading to NULL or broken TLS slot pointers and segfaults. | |
18 | ||
19 | Fix this by resetting the generation to zero in _dl_assign_tls_modid(), | |
20 | so it behaves the same as the first time a slot is assigned. | |
21 | _dl_add_to_slotinfo() will still assign the correct static generation | |
22 | later during module load, but relocation processing will no longer use | |
23 | an obsolete generation. | |
24 | ||
25 | Note that slotinfo entry (aka modid) reuse typically happens after a | |
26 | dlclose and only TLS access via dynamic tlsdesc is affected. Because | |
27 | tlsdesc is optimized to use the optional part of static TLS, dynamic | |
28 | tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls | |
29 | tunable to a large enough value, or by LD_PRELOAD-ing the affected | |
30 | modules. | |
31 | ||
32 | Fixes bug 29039. | |
33 | ||
34 | Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com> | |
35 | (cherry picked from commit 3921c5b40f293c57cb326f58713c924b0662ef59) | |
36 | --- | |
37 | elf/dl-tls.c | 1 + | |
38 | 1 file changed, 1 insertion(+) | |
39 | ||
40 | diff --git a/elf/dl-tls.c b/elf/dl-tls.c | |
41 | index 99b83ca696..1f6f820819 100644 | |
42 | --- a/elf/dl-tls.c | |
43 | +++ b/elf/dl-tls.c | |
44 | @@ -154,6 +154,7 @@ _dl_assign_tls_modid (struct link_map *l) | |
45 | { | |
46 | /* Mark the entry as used, so any dependency see it. */ | |
47 | atomic_store_relaxed (&runp->slotinfo[result - disp].map, l); | |
48 | + atomic_store_relaxed (&runp->slotinfo[result - disp].gen, 0); | |
49 | break; | |
50 | } | |
51 | ||
52 | -- | |
53 | 2.39.2 | |
54 |