Re: [PATCH 1/2] elf: Honour skip_ifunc for cross-object IFUNC relocations [BZ #34428]
"H.J. Lu" <[email protected]> Mon, 3 Aug 2026 08:28:09 +0800
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <CAMe9rOp8Ni7xbcen3654n3V4R6O0Tyx_LKJtJof4cv-o0t3KoQ@mail.gmail.com> |
On Mon, Aug 3, 2026 at 8:11=E2=80=AFAM H.J. Lu <[email protected]> wrote: > > On Mon, Aug 3, 2026 at 7:45=E2=80=AFAM Adhemerval Zanella > <[email protected]> wrote: > > > > Commit 63b31c05a8a dropped the skip_ifunc argument from elf_dynamic_do_= Rel, > > assuming the elf_dynamic_do_Rel_irelative pass handles every relocation > > that may run an IFUNC resolver. That only holds for IFUNC symbols defi= ned > > in the object being relocated, a reference to an IFUNC in another objec= t is > > an ordinary JMP_SLOT or GLOB_DAT against an undefined symbol, and being > > IFUNC is only known after symbol resolution (elf_machine_rel). Those > > relocations stay in the regular pass, which no longer propagated > > skip_ifunc, so __RTLD_NOIFUNC was ignored for them. > > > > ldd -u forces non-lazy binding (GLRO(dl_lazy) =3D 0 for DL_DEBUG_UNUSED= ), so > > the resolver was called and the diagnostic emitted: > > > > $ ldd -u /bin/ls > > /bin/ls: Relink `' with `/usr/lib64/libc.so.6' for IFUNC symbol `__me= mpcpy_chk' > > > > ldd -r with LD_BIND_NOW is affected in the same way. > > > > Restore the skip_ifunc parameter and pass it through _ELF_DYNAMIC_DO_RE= LOC > > and ELF_DYNAMIC_RELOCATE_NOIFUNC. > > > > Checked on x86_64-linux-gnu, aarch64-linux-gnu, and i686-linux-gnu. I > > also built for all supported architectures and run the elf tests on > > qemu-system for armhf, alpha, hppa, loongarch64, mipsel, mips64le, > > powerpc*, riscv64, s390x, and sparc64. > > --- > > elf/Makefile | 28 +++++++++++++++++++++++ > > elf/dl-reloc-static-pie.c | 2 +- > > elf/dl-reloc.c | 3 ++- > > elf/do-rel.h | 24 ++++++++++++------- > > elf/dynamic-link.h | 32 ++++++++++++++++---------- > > elf/tst-ifunc-fault-dep-bindnow.c | 19 ++++++++++++++++ > > elf/tst-ifunc-fault-dep-lazy.c | 27 ++++++++++++++++++++++ > > elf/tst-ifunc-fault-mod.c | 38 +++++++++++++++++++++++++++++++ > > 8 files changed, 151 insertions(+), 22 deletions(-) > > create mode 100644 elf/tst-ifunc-fault-dep-bindnow.c > > create mode 100644 elf/tst-ifunc-fault-dep-lazy.c > > create mode 100644 elf/tst-ifunc-fault-mod.c > > > > diff --git a/elf/Makefile b/elf/Makefile > > index 94c5b7e6ed8..6cfb1b5cf30 100644 > > --- a/elf/Makefile > > +++ b/elf/Makefile > > @@ -1396,6 +1396,13 @@ modules-names +=3D \ > > tst-ifunc-tls-write-lib \ > > tst-tls-tdata-reloc-lib \ > > # modules-names > > +ifeq (yes,$(have-gcc-ifunc)) > > +tests +=3D \ > > + tst-ifunc-fault-dep-bindnow \ > > + tst-ifunc-fault-dep-lazy \ > > + # tests > > +modules-names +=3D tst-ifunc-fault-mod > > +endif > > ifneq (no,$(have-test-mtls-descriptor)) > > tests +=3D tst-ifunc-tls-init-tlsdesc > > modules-names +=3D tst-ifunc-tls-init-tlsdesc-lib > > @@ -2545,6 +2552,27 @@ $(objpfx)tst-ifunc-fault-bindnow.out: $(objpfx)t= st-ifunc-fault-bindnow \ > > $(objpfx)ld.so > > $(tst-ifunc-fault-script) > > > > +LDFLAGS-tst-ifunc-fault-dep-lazy =3D -Wl,-z,lazy > > +LDFLAGS-tst-ifunc-fault-dep-bindnow =3D -Wl,-z,now > > +define tst-ifunc-fault-dep-script > > +( $(test-wrapper) $(rtld-prefix) --verify $< \ > > + && $(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=3D1 $(rtld-prefix) $<= \ > > + && $(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=3D1 LD_DEBUG=3Dunused= \ > > + $(rtld-prefix) $< \ > > + && $(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=3D1 LD_WARN=3Dyes LD_= BIND_NOW=3D1 \ > > + $(rtld-prefix) $< \ > > +) > $@; $(evaluate-test) > > +endef > > +$(objpfx)tst-ifunc-fault-dep-lazy: $(objpfx)tst-ifunc-fault-mod.so > > +$(objpfx)tst-ifunc-fault-dep-bindnow: $(objpfx)tst-ifunc-fault-mod.so > > +$(objpfx)tst-ifunc-fault-dep-lazy.out: $(objpfx)tst-ifunc-fault-dep-la= zy \ > > + $(objpfx)tst-ifunc-fault-mod.so $(objpfx)ld.so > > + $(tst-ifunc-fault-dep-script) > > +$(objpfx)tst-ifunc-fault-dep-bindnow.out: \ > > + $(objpfx)tst-ifunc-fault-dep-bindnow \ > > + $(objpfx)tst-ifunc-fault-mod.so $(objpfx)ld.so > > + $(tst-ifunc-fault-dep-script) > > + > > LDFLAGS-tst-ifunc-plt-lib.so =3D -Wl,-z,lazy > > > > tst-ifunc-plt-bindnow-ENV =3D LD_BIND_NOW=3D1 > > diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c > > index 8463e46147d..53260b57372 100644 > > --- a/elf/dl-reloc-static-pie.c > > +++ b/elf/dl-reloc-static-pie.c > > @@ -80,7 +80,7 @@ _dl_relocate_static_pie (void) > > > > /* Relocate ourselves so we can do normal function calls and data ac= cess > > using the global offset table. IRELATIVE entries are deferred. = */ > > - ELF_DYNAMIC_RELOCATE_NOIFUNC (main_map, NULL, 0, 0); > > + ELF_DYNAMIC_RELOCATE_NOIFUNC (main_map, NULL, 0, 0, 0); > > > > /* Initialize _r_debug_extended. */ > > struct r_debug *r =3D _dl_debug_initialize (0, LM_ID_BASE); > > diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c > > index 15a6a4cffef..80cd7e25d16 100644 > > --- a/elf/dl-reloc.c > > +++ b/elf/dl-reloc.c > > @@ -278,7 +278,8 @@ _dl_relocate_object_no_relro (struct link_map *l, s= truct r_scope_elem *scope[], > > IFUNC resolvers. Without this, a resolver would see the unrelo= cated > > initialiser bytes that were placed into the slot by the early > > _dl_allocate_tls_init. */ > > - ELF_DYNAMIC_RELOCATE_NOIFUNC (l, scope, lazy, consider_profiling); > > + ELF_DYNAMIC_RELOCATE_NOIFUNC (l, scope, lazy, consider_profiling, > > + skip_ifunc); > > ELF_DYNAMIC_RELOCATE_NOIFUNC name is confusing. > If it is NOIFUNC, why isn't IFUNC skipped? > There are /* Like ELF_DYNAMIC_RELOCATE but only processes the non-IRELATIVE pass. The IRELATIVE pass must be completed later via ELF_DYNAMIC_RELOCATE_IFUN= C. Used by the static-pie startup so the TCB and stack-protector canary can be initialised between the two passes. */ # define ELF_DYNAMIC_RELOCATE_NOIFUNC(map, scope, lazy, consider_profile) This change makes the comments incorrect. --=20 H.J.