Re: [PATCH 1/2] elf: Honour skip_ifunc for cross-object IFUNC relocations [BZ #34428]
"H.J. Lu" <[email protected]> Mon, 3 Aug 2026 09:04:41 +0800
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <CAMe9rOoq0C0LanJyF32x3WFU+E42r+ehup5658_tcE0yEYwHcQ@mail.gmail.com> |
On Mon, Aug 3, 2026 at 8:28=E2=80=AFAM H.J. Lu <[email protected]> wrote: > > On Mon, Aug 3, 2026 at 8:11=E2=80=AFAM H.J. Lu <[email protected]> wrot= e: > > > > 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_d= o_Rel, > > > assuming the elf_dynamic_do_Rel_irelative pass handles every relocati= on > > > that may run an IFUNC resolver. That only holds for IFUNC symbols de= fined > > > in the object being relocated, a reference to an IFUNC in another obj= ect is > > > an ordinary JMP_SLOT or GLOB_DAT against an undefined symbol, and bei= ng > > > 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_UNUS= ED), 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 `__= mempcpy_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_= RELOC > > > 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= )tst-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=3Dunus= ed \ > > > + $(rtld-prefix) $< \ > > > + && $(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=3D1 LD_WARN=3Dyes L= D_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.s= o > > > +$(objpfx)tst-ifunc-fault-dep-lazy.out: $(objpfx)tst-ifunc-fault-dep-= lazy \ > > > + $(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 = access > > > 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,= struct r_scope_elem *scope[], > > > IFUNC resolvers. Without this, a resolver would see the unre= located > > > 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_IF= UNC. > Used by the static-pie startup so the TCB and stack-protector canary c= an > be initialised between the two passes. */ > # define ELF_DYNAMIC_RELOCATE_NOIFUNC(map, scope, lazy, consider_profile) > > This change makes the comments incorrect. Can ELF_DYNAMIC_RELOCATE_NOIFUNC/ELF_DYNAMIC_RELOCATE_IFUNC be renamed to ELF_DYNAMIC_RELOCATE_PASS: # define ELF_DYNAMIC_RELOCATE_PASS(pass, map, scope, lazy, skip_ifunc) --=20 H.J.