Fix thread local storage corruption (#1974970)
This commit is contained in:
parent
063fe63eaf
commit
947a02c4ad
|
@ -0,0 +1,88 @@
|
||||||
|
See: https://sourceware.org/pipermail/libc-alpha/2021-June/128024.html
|
||||||
|
|
||||||
|
Until the gap reuse logic is fixed we need to revert the relevant
|
||||||
|
commit.
|
||||||
|
|
||||||
|
This commit reverts the following commit:
|
||||||
|
|
||||||
|
commit 572bd547d57a39b6cf0ea072545dc4048921f4c3
|
||||||
|
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Thu Dec 31 13:59:38 2020 +0000
|
||||||
|
|
||||||
|
elf: Fix DTV gap reuse logic [BZ #27135]
|
||||||
|
|
||||||
|
For some reason only dlopen failure caused dtv gaps to be reused.
|
||||||
|
|
||||||
|
It is possible that the intent was to never reuse modids for a
|
||||||
|
different module, but after dlopen failure all gaps are reused
|
||||||
|
not just the ones caused by the unfinished dlopened.
|
||||||
|
|
||||||
|
So the code has to handle reused modids already which seems to
|
||||||
|
work, however the data races at thread creation and tls access
|
||||||
|
(see bug 19329 and bug 27111) may be more severe if slots are
|
||||||
|
reused so this is scheduled after those fixes. I think fixing
|
||||||
|
the races are not simpler if reuse is disallowed and reuse has
|
||||||
|
other benefits, so set GL(dl_tls_dtv_gaps) whenever entries are
|
||||||
|
removed from the middle of the slotinfo list. The value does
|
||||||
|
not have to be correct: incorrect true value causes the next
|
||||||
|
modid query to do a slotinfo walk, incorrect false will leave
|
||||||
|
gaps and new entries are added at the end.
|
||||||
|
|
||||||
|
Fixes bug 27135.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 9f31532f4145cec5..3720e47dd19bc830 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -88,11 +88,7 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
|
||||||
|
/* If this is not the last currently used entry no need to look
|
||||||
|
further. */
|
||||||
|
if (idx != GL(dl_tls_max_dtv_idx))
|
||||||
|
- {
|
||||||
|
- /* There is an unused dtv entry in the middle. */
|
||||||
|
- GL(dl_tls_dtv_gaps) = true;
|
||||||
|
- return true;
|
||||||
|
- }
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0))
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index d2240d87474e0b85..a066f39bd09131f1 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -899,6 +899,16 @@ no more namespaces available for dlmopen()"));
|
||||||
|
state if relocation failed, for example. */
|
||||||
|
if (args.map)
|
||||||
|
{
|
||||||
|
+ /* Maybe some of the modules which were loaded use TLS.
|
||||||
|
+ Since it will be removed in the following _dl_close call
|
||||||
|
+ we have to mark the dtv array as having gaps to fill the
|
||||||
|
+ holes. This is a pessimistic assumption which won't hurt
|
||||||
|
+ if not true. There is no need to do this when we are
|
||||||
|
+ loading the auditing DSOs since TLS has not yet been set
|
||||||
|
+ up. */
|
||||||
|
+ if ((mode & __RTLD_AUDIT) == 0)
|
||||||
|
+ GL(dl_tls_dtv_gaps) = true;
|
||||||
|
+
|
||||||
|
_dl_close_worker (args.map, true);
|
||||||
|
|
||||||
|
/* All l_nodelete_pending objects should have been deleted
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index e531ec5913d61848..2b5161d10ab1b3d9 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -191,7 +191,10 @@ _dl_next_tls_modid (void)
|
||||||
|
size_t
|
||||||
|
_dl_count_modids (void)
|
||||||
|
{
|
||||||
|
- /* The count is the max unless dlclose or failed dlopen created gaps. */
|
||||||
|
+ /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
|
||||||
|
+ we fail to load a module and unload it leaving a gap. If we don't
|
||||||
|
+ have gaps then the number of modids is the current maximum so
|
||||||
|
+ return that. */
|
||||||
|
if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
|
||||||
|
return GL(dl_tls_max_dtv_idx);
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: %{glibcversion}
|
Version: %{glibcversion}
|
||||||
Release: 24%{?dist}
|
Release: 25%{?dist}
|
||||||
|
|
||||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||||
# libraries.
|
# libraries.
|
||||||
|
@ -179,6 +179,7 @@ Patch35: glibc-nosymlink-2.patch
|
||||||
Patch36: glibc-nosymlink-3.patch
|
Patch36: glibc-nosymlink-3.patch
|
||||||
Patch37: glibc-nosymlink-4.patch
|
Patch37: glibc-nosymlink-4.patch
|
||||||
Patch38: glibc-libthread_db-dynsym.patch
|
Patch38: glibc-libthread_db-dynsym.patch
|
||||||
|
Patch39: glibc-revert-dtv-gap-reuse.patch
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Continued list of core "glibc" package information:
|
# Continued list of core "glibc" package information:
|
||||||
|
@ -2182,6 +2183,9 @@ fi
|
||||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jun 24 2021 Carlos O'Donell <carlos@redhat.com> - 2.33.9000-25
|
||||||
|
- Fix thread local storage corruption (#1974970)
|
||||||
|
|
||||||
* Tue Jun 22 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.33.9000-24
|
* Tue Jun 22 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.33.9000-24
|
||||||
- Strengthen dependency on glibc-gconv-extra.
|
- Strengthen dependency on glibc-gconv-extra.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue