forked from rpms/glibc
elf: Rework exception handling in the dynamic loader (RHEL-46979)
Resolves: RHEL-46979 Note glibc-RHEL-46979-3.patch contains backport-related ABI protection and is not an upstream commit.
This commit is contained in:
parent
8e284fa1e8
commit
3d4f500e5c
83
glibc-RHEL-46979-1.patch
Normal file
83
glibc-RHEL-46979-1.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From a65ff76c9a1811dd2396ab45563f645579c0e687 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 27 Oct 2022 11:36:44 +0200
|
||||
Subject: ld.so: Export tls_init_tp_called as __rtld_tls_init_tp_called
|
||||
|
||||
This allows the rest of dynamic loader to check whether the TCB
|
||||
has been set up (and THREAD_GETMEM and THREAD_SETMEM will work).
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
|
||||
|
||||
Conflicts:
|
||||
Regenerated for context changes.
|
||||
|
||||
diff -rup a/elf/rtld.c b/elf/rtld.c
|
||||
--- a/elf/rtld.c 2024-08-22 17:57:02.000830481 -0400
|
||||
+++ b/elf/rtld.c 2024-08-22 17:59:30.666562835 -0400
|
||||
@@ -740,7 +740,7 @@ match_version (const char *string, struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static bool tls_init_tp_called;
|
||||
+bool __rtld_tls_init_tp_called;
|
||||
|
||||
static void *
|
||||
init_tls (size_t naudit)
|
||||
@@ -812,7 +812,7 @@ cannot allocate TLS data structures for
|
||||
if (__glibc_unlikely (lossage != NULL))
|
||||
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
|
||||
__tls_init_tp ();
|
||||
- tls_init_tp_called = true;
|
||||
+ __rtld_tls_init_tp_called = true;
|
||||
|
||||
return tcbp;
|
||||
}
|
||||
@@ -2057,7 +2057,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
|
||||
used. Trying to do it lazily is too hairy to try when there could be
|
||||
multiple threads (from a non-TLS-using libpthread). */
|
||||
- bool was_tls_init_tp_called = tls_init_tp_called;
|
||||
+ bool was_tls_init_tp_called = __rtld_tls_init_tp_called;
|
||||
if (tcbp == NULL)
|
||||
tcbp = init_tls (0);
|
||||
|
||||
@@ -2411,7 +2411,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
_dl_protect_relro (l);
|
||||
|
||||
/* Add object to slot information data if necessasy. */
|
||||
- if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||
+ if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called)
|
||||
_dl_add_to_slotinfo (l, true);
|
||||
}
|
||||
}
|
||||
@@ -2462,7 +2462,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
consider_profiling);
|
||||
|
||||
/* Add object to slot information data if necessasy. */
|
||||
- if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||
+ if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called)
|
||||
_dl_add_to_slotinfo (l, true);
|
||||
}
|
||||
rtld_timer_stop (&relocate_time, start);
|
||||
@@ -2488,7 +2488,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
_dl_allocate_tls_init (tcbp, true);
|
||||
|
||||
/* And finally install it for the main thread. */
|
||||
- if (! tls_init_tp_called)
|
||||
+ if (! __rtld_tls_init_tp_called)
|
||||
{
|
||||
const char *lossage = TLS_INIT_TP (tcbp);
|
||||
if (__glibc_unlikely (lossage != NULL))
|
||||
diff -rup a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
--- a/sysdeps/generic/ldsodefs.h 2024-08-22 17:57:02.011830906 -0400
|
||||
+++ b/sysdeps/generic/ldsodefs.h 2024-08-22 17:58:10.900487160 -0400
|
||||
@@ -1262,6 +1262,9 @@ extern void *_dl_allocate_tls_storage (v
|
||||
extern void *_dl_allocate_tls_init (void *result, bool main_thread);
|
||||
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||
|
||||
+/* True if the TCB has been set up. */
|
||||
+extern bool __rtld_tls_init_tp_called attribute_hidden;
|
||||
+
|
||||
/* Deallocate memory allocated with _dl_allocate_tls. */
|
||||
extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb);
|
||||
rtld_hidden_proto (_dl_deallocate_tls)
|
1030
glibc-RHEL-46979-2.patch
Normal file
1030
glibc-RHEL-46979-2.patch
Normal file
File diff suppressed because it is too large
Load Diff
82
glibc-RHEL-46979-3.patch
Normal file
82
glibc-RHEL-46979-3.patch
Normal file
@ -0,0 +1,82 @@
|
||||
Extra changes needed for backport:
|
||||
|
||||
* rename field "rtld_catch" to "rtld_catch_f" to avoid conflict
|
||||
between "struct rtld-catch" and rtld_catch macro
|
||||
|
||||
* move rtld_catch into one of the unused padding fields to preserve
|
||||
ABI
|
||||
|
||||
* Validate that the padding fields used don't overlap other fields.
|
||||
|
||||
diff -rup a/elf/dl-catch.c b/elf/dl-catch.c
|
||||
--- a/elf/dl-catch.c 2024-09-04 16:30:02.086402568 -0400
|
||||
+++ b/elf/dl-catch.c 2024-09-04 16:55:01.933440181 -0400
|
||||
@@ -59,7 +59,7 @@ get_catch (void)
|
||||
return rtld_catch_notls;
|
||||
else
|
||||
#endif
|
||||
- return THREAD_GETMEM (THREAD_SELF, rtld_catch);
|
||||
+ return THREAD_GETMEM (THREAD_SELF, rtld_catch_f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -70,7 +70,7 @@ set_catch (struct rtld_catch *catch)
|
||||
rtld_catch_notls = catch;
|
||||
else
|
||||
#endif
|
||||
- THREAD_SETMEM (THREAD_SELF, rtld_catch, catch);
|
||||
+ THREAD_SETMEM (THREAD_SELF, rtld_catch_f, catch);
|
||||
}
|
||||
|
||||
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||
diff -rup a/nptl/descr.h b/nptl/descr.h
|
||||
--- a/nptl/descr.h 2024-08-29 11:29:16.801811033 -0400
|
||||
+++ b/nptl/descr.h 2024-08-29 11:48:56.547644398 -0400
|
||||
@@ -164,6 +164,12 @@ struct pthread
|
||||
void *__padding[24];
|
||||
};
|
||||
|
||||
+#ifdef __x86_64__
|
||||
+#define rtld_catch_f header.__padding[7]
|
||||
+#else
|
||||
+#define rtld_catch_f __padding[23]
|
||||
+#endif
|
||||
+
|
||||
/* This descriptor's link on the GL (dl_stack_used) or
|
||||
GL (dl_stack_user) list. */
|
||||
list_t list;
|
||||
@@ -396,9 +402,6 @@ struct pthread
|
||||
masked.) */
|
||||
sigset_t sigmask;
|
||||
|
||||
- /* Used by the exception handling implementation in the dynamic loader. */
|
||||
- struct rtld_catch *rtld_catch;
|
||||
-
|
||||
/* Indicates whether is a C11 thread created by thrd_creat. */
|
||||
bool c11;
|
||||
|
||||
@@ -432,6 +435,12 @@ struct pthread
|
||||
+ sizeof ((struct pthread) {}.rseq_area))
|
||||
} __attribute ((aligned (TCB_ALIGNMENT)));
|
||||
|
||||
+#ifdef __x86_64__
|
||||
+_Static_assert (sizeof ((*(struct pthread *)0).header) > sizeof ((*(struct pthread *)0).__padding), "rtld_catch");
|
||||
+#else
|
||||
+_Static_assert (sizeof ((*(struct pthread *)0).header) < sizeof ((*(struct pthread *)0).__padding), "rtld_catch");
|
||||
+#endif
|
||||
+
|
||||
static inline bool
|
||||
cancel_enabled_and_canceled (int value)
|
||||
{
|
||||
diff -rup a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
|
||||
--- a/sysdeps/mach/hurd/i386/tls.h 2024-08-29 11:29:16.810811382 -0400
|
||||
+++ b/sysdeps/mach/hurd/i386/tls.h 2024-08-29 11:35:45.262899113 -0400
|
||||
@@ -50,7 +50,7 @@ typedef struct
|
||||
struct hurd_sigstate *_hurd_sigstate;
|
||||
|
||||
/* Used by the exception handling implementation in the dynamic loader. */
|
||||
- struct rtld_catch *rtld_catch;
|
||||
+ struct rtld_catch *rtld_catch_f;
|
||||
} tcbhead_t;
|
||||
#endif
|
||||
|
79
glibc-RHEL-46979-4.patch
Normal file
79
glibc-RHEL-46979-4.patch
Normal file
@ -0,0 +1,79 @@
|
||||
New test case to verify padding usage.
|
||||
|
||||
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||
index ff4d590f11c38277..9a56d34313d06444 100644
|
||||
--- a/nptl/Makefile
|
||||
+++ b/nptl/Makefile
|
||||
@@ -319,6 +319,8 @@ tests-internal := tst-robustpi8 tst-rwlock19 tst-rwlock20 \
|
||||
tst-barrier5 tst-signal7 tst-mutex8 tst-mutex8-static \
|
||||
tst-mutexpi8 tst-mutexpi8-static \
|
||||
tst-setgetname \
|
||||
+ tst-nptl-padding \
|
||||
+ # tests-internal
|
||||
|
||||
xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
|
||||
tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 tst-setgroups \
|
||||
diff --git a/nptl/tst-nptl-padding.c b/nptl/tst-nptl-padding.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5bb64f4a54335e36
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-nptl-padding.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+/* Downstream-only test for verifying that fields that have been
|
||||
+ relocated into struct pthread padding actually use the padding.
|
||||
+
|
||||
+ At present, only rtld_catch (downstream: rtld_catch_f) has been
|
||||
+ placed into padding. */
|
||||
+
|
||||
+#include <descr.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct pthread descr;
|
||||
+
|
||||
+ /* Mark the entire descriptor as used. */
|
||||
+ memset (&descr, 0xff, sizeof (descr));
|
||||
+
|
||||
+ /* Mark the padding as unused. */
|
||||
+#ifdef __x86_64__
|
||||
+ /* Special case: Usable padding is in the header. */
|
||||
+ memset (&descr.header.__padding, 0, sizeof (descr.header.__padding));
|
||||
+#else
|
||||
+ /* The padding should be directly adjacent to the first real
|
||||
+ struct field. */
|
||||
+ TEST_COMPARE (sizeof (descr.__padding), offsetof (struct pthread, list));
|
||||
+
|
||||
+ /* Clear the unused tail of the padding. */
|
||||
+ {
|
||||
+ char *base = (char *) &descr;
|
||||
+ char *end_of_header = base + sizeof (descr.header);
|
||||
+ char *end_of_padding = base + sizeof (descr.__padding);
|
||||
+ memset (end_of_header, 0, end_of_padding - end_of_header);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* These fields are not in padding and should remain marked as used. */
|
||||
+ TEST_COMPARE (descr.header.gscope_flag, -1);
|
||||
+ TEST_COMPARE ((intptr_t) descr.list.next, -1);
|
||||
+ TEST_COMPARE ((intptr_t) descr.list.prev, -1);
|
||||
+
|
||||
+ /* But this field remains in padding. */
|
||||
+ TEST_COMPARE ((intptr_t) descr.rtld_catch_f, 0);
|
||||
+
|
||||
+ /* Write to all padding-relocated fields below to show that they
|
||||
+ have independent locations. */
|
||||
+ struct rtld_catch *rtld_catch_dummy = (void *) "rtld_catch_dummy";
|
||||
+ descr.rtld_catch_f = rtld_catch_dummy;
|
||||
+
|
||||
+ TEST_VERIFY (descr.rtld_catch_f == rtld_catch_dummy);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
@ -157,7 +157,7 @@ end \
|
||||
Summary: The GNU libc libraries
|
||||
Name: glibc
|
||||
Version: %{glibcversion}
|
||||
Release: 124%{?dist}
|
||||
Release: 125%{?dist}
|
||||
|
||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||
# libraries.
|
||||
@ -865,6 +865,10 @@ Patch626: glibc-RHEL-54447-7.patch
|
||||
Patch627: glibc-RHEL-54447-8.patch
|
||||
Patch628: glibc-RHEL-54447-9.patch
|
||||
Patch629: glibc-RHEL-54447-10.patch
|
||||
Patch630: glibc-RHEL-46979-1.patch
|
||||
Patch631: glibc-RHEL-46979-2.patch
|
||||
Patch632: glibc-RHEL-46979-3.patch
|
||||
Patch633: glibc-RHEL-46979-4.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -3024,6 +3028,9 @@ update_gconv_modules_cache ()
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Sep 5 2024 DJ Delorie <dj@redhat.com> - 2.34-125
|
||||
- elf: Rework exception handling in the dynamic loader (RHEL-46979)
|
||||
|
||||
* Thu Sep 5 2024 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.34-124
|
||||
- Fix ungetc leak and invalid read (RHEL-54447)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user