[PATCH 0/2] elf: Make IFUNC resolvers see a usable process state
Adhemerval Zanella
adhemerval.zanella@linaro.org
Fri May 22 17:08:11 GMT 2026
This series addresses two long-standing classes of IFUNC resolver
crashes / silent miscompilations, all caused by resolvers firing before
the process state they depend on is initialised.
Patch 1 fixes the dynamic linker side: an IFUNC resolver firing during
rtld's relocation loop would read its DSO's __thread storage from a
zero-filled slot, because the trailing _dl_allocate_tls_init at the end
of dl_main had not copied TLS data yet. A resolver that *wrote* TLS was
worse off -- the write got clobbered by that same trailing copy. Moving
_dl_allocate_tls_init ahead of the relocation loop closes the read window
and makes writes survive.
Patch 2 fixes the static-link side: apply_irel for non-PIE and the
IRELATIVE phase inside _dl_relocate_static_pie for static-pie
both ran before __libc_setup_tls and before _dl_setup_stack_chk_guard.
A resolver compiled with -fstack-protector(-all) crashed (TCB-canary
ABIs: x86_64, i386, powerpc, s390) or silently loaded a zero canary
(other ABIs). A resolver reading any thread-local hit the same trap.
This patch reorders csu/libc-start.c to set up the TCB and write the
canary / pointer guard before any IFUNC resolver runs, splitting
_dl_relocate_static_pie into two phases so the setup can happen between
them.
Bugs closed:
BZ #20673 resolver TLS read/write (dynamic) -- patch 1
BZ #34164 same, with a stronger fix and tests -- patch 1
BZ #20680 resolver TLS read / canary (static) -- patch 2
BZ #27582 resolver stack-protector (umbrella) -- patch 2
BZ #28817 static-pie TLS in resolver -- patch 2
BZ #28218 cross-DSO IFUNC resolver chain -- already fixed
by 63b31c05a8a; this series adds the regression test
Tested across every Linux ABI in the build tree that has have-gcc-ifunc:
aarch64, arm, armeb, i686, loongarch64, powerpc, powerpc-power4,
powerpc-soft, powerpc64, powerpc64le, riscv32, riscv64, s390x,
sparc64, sparcv9 and x86_64 (sparc has have-ifunc=no so the dynamic
regression test is skipped there). Builds also clean on the Hurd
(i686-gnu, x86_64-gnu) and x86_64-x32.
Adhemerval Zanella (2):
elf: Initialize static TLS before relocation processing (BZ 34164)
elf: Initialize TCB and stack-protector before static IFUNC resolvers
(BZ 20680, BZ 27582, BZ 28817)
csu/libc-start.c | 40 +++++----
csu/static-reloc.c | 5 ++
elf/Makefile | 53 +++++++++++-
elf/dl-reloc-static-pie.c | 24 ++++--
elf/dl-reloc.c | 27 +++---
elf/dynamic-link.h | 84 +++++++++++++++----
elf/rtld.c | 31 ++++---
elf/tst-ifunc-bz28817.c | 60 +++++++++++++
elf/tst-ifunc-resolver-protector-mod.c | 61 ++++++++++++++
elf/tst-ifunc-resolver-protector-static-mod.c | 68 +++++++++++++++
...nc-resolver-protector-static-non-pie-mod.c | 2 +
...-ifunc-resolver-protector-static-non-pie.c | 5 ++
elf/tst-ifunc-resolver-protector-static.c | 61 ++++++++++++++
elf/tst-ifunc-resolver-protector.c | 42 ++++++++++
elf/tst-ifunc-tls-init-dlopen-lib.c | 55 ++++++++++++
elf/tst-ifunc-tls-init-lib-skeleton.c | 57 +++++++++++++
elf/tst-ifunc-tls-init-lib1.c | 1 +
elf/tst-ifunc-tls-init-lib2.c | 1 +
elf/tst-ifunc-tls-init.c | 81 ++++++++++++++++++
elf/tst-ifunc-tls-write-lib.c | 54 ++++++++++++
.../libc-start.h => elf/tst-ifunc-tls-write.c | 28 ++++---
.../aarch64/multiarch/dl-symbol-redir-ifunc.h | 4 +
sysdeps/generic/ldsodefs.h | 7 +-
sysdeps/generic/libc-start.h | 9 +-
.../lp64/multiarch/dl-symbol-redir-ifunc.h | 2 +
sysdeps/unix/sysv/linux/aarch64/libc-start.h | 1 -
sysdeps/x86_64/libc-start.h | 1 -
.../x86_64/multiarch/dl-symbol-redir-ifunc.h | 19 +++++
28 files changed, 799 insertions(+), 84 deletions(-)
create mode 100644 elf/tst-ifunc-bz28817.c
create mode 100644 elf/tst-ifunc-resolver-protector-mod.c
create mode 100644 elf/tst-ifunc-resolver-protector-static-mod.c
create mode 100644 elf/tst-ifunc-resolver-protector-static-non-pie-mod.c
create mode 100644 elf/tst-ifunc-resolver-protector-static-non-pie.c
create mode 100644 elf/tst-ifunc-resolver-protector-static.c
create mode 100644 elf/tst-ifunc-resolver-protector.c
create mode 100644 elf/tst-ifunc-tls-init-dlopen-lib.c
create mode 100644 elf/tst-ifunc-tls-init-lib-skeleton.c
create mode 100644 elf/tst-ifunc-tls-init-lib1.c
create mode 100644 elf/tst-ifunc-tls-init-lib2.c
create mode 100644 elf/tst-ifunc-tls-init.c
create mode 100644 elf/tst-ifunc-tls-write-lib.c
rename sysdeps/unix/sysv/linux/powerpc/libc-start.h => elf/tst-ifunc-tls-write.c (61%)
--
2.43.0
More information about the Libc-alpha
mailing list