[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