You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
47 lines
2.1 KiB
47 lines
2.1 KiB
commit 3921c5b40f293c57cb326f58713c924b0662ef59 |
|
Author: Hector Martin <marcan@marcan.st> |
|
Date: Tue Nov 28 15:23:07 2023 +0900 |
|
|
|
elf: Fix TLS modid reuse generation assignment (BZ 29039) |
|
|
|
_dl_assign_tls_modid() assigns a slotinfo entry for a new module, but |
|
does *not* do anything to the generation counter. The first time this |
|
happens, the generation is zero and map_generation() returns the current |
|
generation to be used during relocation processing. However, if |
|
a slotinfo entry is later reused, it will already have a generation |
|
assigned. If this generation has fallen behind the current global max |
|
generation, then this causes an obsolete generation to be assigned |
|
during relocation processing, as map_generation() returns this |
|
generation if nonzero. _dl_add_to_slotinfo() eventually resets the |
|
generation, but by then it is too late. This causes DTV updates to be |
|
skipped, leading to NULL or broken TLS slot pointers and segfaults. |
|
|
|
Fix this by resetting the generation to zero in _dl_assign_tls_modid(), |
|
so it behaves the same as the first time a slot is assigned. |
|
_dl_add_to_slotinfo() will still assign the correct static generation |
|
later during module load, but relocation processing will no longer use |
|
an obsolete generation. |
|
|
|
Note that slotinfo entry (aka modid) reuse typically happens after a |
|
dlclose and only TLS access via dynamic tlsdesc is affected. Because |
|
tlsdesc is optimized to use the optional part of static TLS, dynamic |
|
tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls |
|
tunable to a large enough value, or by LD_PRELOAD-ing the affected |
|
modules. |
|
|
|
Fixes bug 29039. |
|
|
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com> |
|
|
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c |
|
index b8ada16f1637c910..b9dc56e81a3b43db 100644 |
|
--- a/elf/dl-tls.c |
|
+++ b/elf/dl-tls.c |
|
@@ -160,6 +160,7 @@ _dl_assign_tls_modid (struct link_map *l) |
|
{ |
|
/* Mark the entry as used, so any dependency see it. */ |
|
atomic_store_relaxed (&runp->slotinfo[result - disp].map, l); |
|
+ atomic_store_relaxed (&runp->slotinfo[result - disp].gen, 0); |
|
break; |
|
} |
|
|
|
|