summaryrefslogtreecommitdiff
path: root/backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
diff options
context:
space:
mode:
Diffstat (limited to 'backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch')
-rw-r--r--backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch54
1 files changed, 54 insertions, 0 deletions
diff --git a/backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch b/backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
new file mode 100644
index 0000000..a709c72
--- /dev/null
+++ b/backport-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
@@ -0,0 +1,54 @@
+From 3921c5b40f293c57cb326f58713c924b0662ef59 Mon Sep 17 00:00:00 2001
+From: Hector Martin <marcan@marcan.st>
+Date: Tue, 28 Nov 2023 15:23:07 +0900
+Subject: [PATCH] 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.
+
+Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=3921c5b40f293c57cb326f58713c924b0662ef59
+
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+---
+ elf/dl-tls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 0070c8bb..42868eef 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;
+ }
+
+--
+2.33.0
+