Message ID | 20220125183700.1280931-4-adhemerval.zanella@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | Multiple rtld-audit fixes | expand |
Context | Check | Description |
---|---|---|
dj/TryBot-apply_patch | success | Patch applied to master at the time it was sent |
On 1/25/22 13:36, Adhemerval Zanella wrote: > The audit symbind callback is not called for binaries built with > -Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks > (plt_enter and plt_exit) since this will would change the expected s/will would/would/g > program semantic (where no PTL is expected) and would incur in s/semantic/semantics/g s/PTL/PLT/g s/incur in/have/g > performance implications (such as for BZ#15533). > > LAV_CURRENT is also bumped to indicate the audit ABI change (where > la_symbind flags are set by the loader to indicate no possible PTL s/PTL/PLT/g > trace). > > To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind > requires to know whether bind-now is used so the symbol value is > updated to function text segment instead of the OPD (for lazy binding > this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve). > > Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, > powerpc64-linux-gnu. Please post v13 and I'll ack that for glibc 2.35. > --- > NEWS | 4 + > bits/link_lavcurrent.h | 2 +- > elf/Makefile | 89 ++++++++++++++++++++++- > elf/dl-audit.c | 58 +++++++++------ > elf/do-rel.h | 57 +++++++++++---- > elf/sotruss-lib.c | 7 ++ > elf/tst-audit24a.c | 36 +++++++++ > elf/tst-audit24amod1.c | 31 ++++++++ > elf/tst-audit24amod2.c | 25 +++++++ > elf/tst-audit24b.c | 37 ++++++++++ > elf/tst-audit24bmod1.c | 31 ++++++++ > elf/tst-audit24bmod2.c | 23 ++++++ > elf/tst-audit24c.c | 2 + > elf/tst-audit24d.c | 36 +++++++++ > elf/tst-audit24dmod1.c | 33 +++++++++ > elf/tst-audit24dmod2.c | 28 +++++++ > elf/tst-audit24dmod3.c | 31 ++++++++ > elf/tst-audit24dmod4.c | 25 +++++++ > elf/tst-audit25a.c | 129 +++++++++++++++++++++++++++++++++ > elf/tst-audit25b.c | 128 ++++++++++++++++++++++++++++++++ > elf/tst-audit25mod1.c | 30 ++++++++ > elf/tst-audit25mod2.c | 30 ++++++++ > elf/tst-audit25mod3.c | 22 ++++++ > elf/tst-audit25mod4.c | 22 ++++++ > elf/tst-auditmod24.h | 29 ++++++++ > elf/tst-auditmod24a.c | 114 +++++++++++++++++++++++++++++ > elf/tst-auditmod24b.c | 104 ++++++++++++++++++++++++++ > elf/tst-auditmod24c.c | 3 + > elf/tst-auditmod24d.c | 120 ++++++++++++++++++++++++++++++ > elf/tst-auditmod25.c | 79 ++++++++++++++++++++ > sysdeps/generic/dl-lookupcfg.h | 3 + > sysdeps/generic/ldsodefs.h | 5 +- > sysdeps/hppa/dl-lookupcfg.h | 3 + > sysdeps/ia64/dl-lookupcfg.h | 3 + > sysdeps/powerpc/dl-lookupcfg.h | 39 ++++++++++ > 35 files changed, 1379 insertions(+), 39 deletions(-) > create mode 100644 elf/tst-audit24a.c > create mode 100644 elf/tst-audit24amod1.c > create mode 100644 elf/tst-audit24amod2.c > create mode 100644 elf/tst-audit24b.c > create mode 100644 elf/tst-audit24bmod1.c > create mode 100644 elf/tst-audit24bmod2.c > create mode 100644 elf/tst-audit24c.c > create mode 100644 elf/tst-audit24d.c > create mode 100644 elf/tst-audit24dmod1.c > create mode 100644 elf/tst-audit24dmod2.c > create mode 100644 elf/tst-audit24dmod3.c > create mode 100644 elf/tst-audit24dmod4.c > create mode 100644 elf/tst-audit25a.c > create mode 100644 elf/tst-audit25b.c > create mode 100644 elf/tst-audit25mod1.c > create mode 100644 elf/tst-audit25mod2.c > create mode 100644 elf/tst-audit25mod3.c > create mode 100644 elf/tst-audit25mod4.c > create mode 100644 elf/tst-auditmod24.h > create mode 100644 elf/tst-auditmod24a.c > create mode 100644 elf/tst-auditmod24b.c > create mode 100644 elf/tst-auditmod24c.c > create mode 100644 elf/tst-auditmod24d.c > create mode 100644 elf/tst-auditmod25.c > create mode 100644 sysdeps/powerpc/dl-lookupcfg.h > > diff --git a/NEWS b/NEWS > index a9f25d3225..c0f8932f84 100644 > --- a/NEWS > +++ b/NEWS > @@ -158,6 +158,10 @@ Deprecated and removed features, and other changes affecting compatibility: > been removed. There are widely-deployed out-of-process alternatives for > catching coredumps and backtraces. > > +* The audit module interface version LAV_CURRENT is increased to enable > + proper bind-now support. The loader now advertises on the la_symbind s/on/via/g > + flags that PLT trace is not possible. > + > Changes to build and runtime requirements: > > [Add changes to build and runtime requirements here] > diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h > index 7bfa4b9f4e..a852d41302 100644 > --- a/bits/link_lavcurrent.h > +++ b/bits/link_lavcurrent.h > @@ -22,4 +22,4 @@ > #endif > > /* Version numbers for la_version handshake interface. */ > -#define LAV_CURRENT 1 > +#define LAV_CURRENT 2 OK. New version. > diff --git a/elf/Makefile b/elf/Makefile > index 7d01b71f6a..b9edcccb82 100644 > --- a/elf/Makefile > +++ b/elf/Makefile > @@ -379,6 +379,12 @@ tests += \ > tst-audit21 \ > tst-audit22 \ > tst-audit23 \ > + tst-audit24a \ > + tst-audit24b \ > + tst-audit24c \ > + tst-audit24d \ > + tst-audit25a \ > + tst-audit25b \ OK. New tests. > tst-auditmany \ > tst-auxobj \ > tst-auxobj-dlopen \ > @@ -676,6 +682,18 @@ modules-names = \ > tst-audit18mod \ > tst-audit19bmod \ > tst-audit23mod \ > + tst-audit24amod1 \ > + tst-audit24amod2 \ > + tst-audit24bmod1 \ > + tst-audit24bmod2 \ > + tst-audit24dmod1 \ > + tst-audit24dmod2 \ > + tst-audit24dmod3 \ > + tst-audit24dmod4 \ > + tst-audit25mod1 \ > + tst-audit25mod2 \ > + tst-audit25mod3 \ > + tst-audit25mod4 \ OK. New DSOs. > tst-auditlogmod-1 \ > tst-auditlogmod-2 \ > tst-auditlogmod-3 \ > @@ -701,6 +719,11 @@ modules-names = \ > tst-auditmod21b \ > tst-auditmod22 \ > tst-auditmod23 \ > + tst-auditmod24a \ > + tst-auditmod24b \ > + tst-auditmod24c \ > + tst-auditmod24d \ > + tst-auditmod25 \ OK. New audit modules. > tst-auxvalmod \ > tst-big-note-lib \ > tst-deep1mod1 \ > @@ -918,7 +941,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) > > # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special > # rules. > -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod > +modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \ > + tst-audit24bmod1 tst-audit24bmod2.so OK. Build them differently. > > tests += $(tests-static) > > @@ -2151,6 +2175,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \ > $(objpfx)tst-audit23mod.so > tst-audit23-ARGS = -- $(host-test-program-cmd) > > +$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so > +$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \ > + $(objpfx)tst-audit24amod2.so > +tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so > +LDFLAGS-tst-audit24a = -Wl,-z,now OK. Ensure immmediate binding. > + > +$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so > +$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \ > + $(objpfx)tst-audit24bmod2.so > +$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so > +# The test check if a library without .gnu.version correctly calls the s/check/checks/g > +# audit callbacks. So it uses an explicit link rule to avoid linking > +# against libc.so. > +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os > + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \ > + -Wl,-z,now > + $(call after-link,$@.new) > + mv -f $@.new $@ OK. > +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1) > +$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os > + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os > + $(call after-link,$@.new) > + mv -f $@.new $@ > +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2) > +tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so > +LDFLAGS-tst-audit24b = -Wl,-z,now OK. > + > +# Same as tst-audit24a, but tests LD_BIND_NOW > +$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so > +$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \ > + $(objpfx)tst-audit24amod2.so > +tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so OK. Immediate binding via env var. > +LDFLAGS-tst-audit24b = -Wl,-z,lazy OK. Testing lazy binding. > + > +$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so > +$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \ > + $(objpfx)tst-audit24dmod2.so > +$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so > +LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now > +$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so > +LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy > +tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so > +LDFLAGS-tst-audit24d = -Wl,-z,lazy > + > +$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so > +$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \ > + $(objpfx)tst-audit25mod2.so \ > + $(objpfx)tst-audit25mod3.so \ > + $(objpfx)tst-audit25mod4.so > +$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so > +LDFLAGS-tst-audit25mod1.so = -Wl,-z,now > +$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so > +LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy > +tst-audit25a-ARGS = -- $(host-test-program-cmd) > + > +$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so > +$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ > + $(objpfx)tst-audit25mod2.so \ > + $(objpfx)tst-audit25mod3.so \ > + $(objpfx)tst-audit25mod4.so > +LDFLAGS-tst-audit25b = -Wl,-z,now > +tst-audit25b-ARGS = -- $(host-test-program-cmd) > + > # tst-sonamemove links against an older implementation of the library. > LDFLAGS-tst-sonamemove-linkmod1.so = \ > -Wl,--version-script=tst-sonamemove-linkmod1.map \ > diff --git a/elf/dl-audit.c b/elf/dl-audit.c > index 715de53272..794bfd45cd 100644 > --- a/elf/dl-audit.c > +++ b/elf/dl-audit.c > @@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, > const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, > lookup_t result) > { > - reloc_result->bound = result; > - /* Compute index of the symbol entry in the symbol table of the DSO with the > - definition. */ > - reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result, > - l_info[DT_SYMTAB])); > + bool for_jmp_slot = reloc_result == NULL; OK. Check if we have relocation result. > + > + /* Compute index of the symbol entry in the symbol table of the DSO > + with the definition. */ > + unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result, > + l_info[DT_SYMTAB]); > + if (!for_jmp_slot) > + { > + reloc_result->bound = result; > + reloc_result->boundndx = boundndx; > + } OK. Need to guard reloc_result around !for_jmp_slot. > > if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) > { > /* Set all bits since this symbol binding is not interesting. */ > - reloc_result->enterexit = (1u << DL_NNS) - 1; > + if (!for_jmp_slot) > + reloc_result->enterexit = (1u << DL_NNS) - 1; OK. > return; > } > > @@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, > two bits. */ > assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8); > assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3); > - reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; > + uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; OK. > > const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); > > unsigned int flags = 0; > struct audit_ifaces *afct = GLRO(dl_audit); > + uintptr_t new_value = (uintptr_t) sym.st_value; > for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) > { > /* XXX Check whether both DSOs must request action or only one */ > @@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, > { > if (afct->symbind != NULL) > { OK. We have an auditor function to call. > - uintptr_t new_value = afct->symbind (&sym, > - reloc_result->boundndx, > - &l_state->cookie, > - &result_state->cookie, > - &flags, > - strtab2 + defsym->st_name); > + flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT > + : 0; OK. Set incoming flags depending on for_jmp_slot. > + new_value = afct->symbind (&sym, boundndx, > + &l_state->cookie, > + &result_state->cookie, &flags, > + strtab2 + defsym->st_name); > if (new_value != (uintptr_t) sym.st_value) > { > flags |= LA_SYMB_ALTVALUE; > - sym.st_value = new_value; > + sym.st_value = for_jmp_slot > + ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value; OK. > } > } > > /* Remember the results for every audit library and store a summary > in the first two bits. */ > - reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER > - | LA_SYMB_NOPLTEXIT); > - reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER > - | LA_SYMB_NOPLTEXIT)) > - << ((cnt + 1) * 2)); > + enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT); > + enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) > + << ((cnt + 1) * 2)); OK. > } > else > /* If the bind flags say this auditor is not interested, set the bits > manually. */ > - reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) > - << ((cnt + 1) * 2)); > + enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) > + << ((cnt + 1) * 2)); OK. > afct = afct->next; > } > > - reloc_result->flags = flags; > - *value = DL_FIXUP_ADDR_VALUE (sym.st_value); > + if (!for_jmp_slot) > + { > + reloc_result->enterexit = enterexit; > + reloc_result->flags = flags; > + } > + > + DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); OK. > } > > void > diff --git a/elf/do-rel.h b/elf/do-rel.h > index 0718badf83..60d5dce8f2 100644 > --- a/elf/do-rel.h > +++ b/elf/do-rel.h > @@ -16,6 +16,8 @@ > License along with the GNU C Library; if not, see > <https://www.gnu.org/licenses/>. */ > > +#include <ldsodefs.h> > + > /* This file may be included twice, to define both > `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ > > @@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], > > for (; r < end; ++r) > { > + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; > + const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; > + void *const r_addr_arg = (void *) (l_addr + r->r_offset); > + const struct r_found_version *rversion = &map->l_versions[ndx]; > #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP > if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) > { > @@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], > } > #endif > > - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; > - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], > - &map->l_versions[ndx], > - (void *) (l_addr + r->r_offset), skip_ifunc); > + elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, > + skip_ifunc); OK. We are in the non-lazy case. > +#if defined SHARED && !defined RTLD_BOOTSTRAP > + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT > + && GLRO(dl_naudit) > 0) > + { > + struct link_map *sym_map > + = RESOLVE_MAP (map, scope, &sym, rversion, > + ELF_MACHINE_JMP_SLOT); OK. Do the extra check at startup. > + if (sym != NULL) > + _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map); OK. Early immeidate binding for symbol. > + } > +#endif > } > > #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP > @@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], > else > { > for (; r < end; ++r) > + { > + const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; > + void *const r_addr_arg = (void *) (l_addr + r->r_offset); > # ifdef ELF_MACHINE_IRELATIVE > - if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) > - { > - if (r2 == NULL) > - r2 = r; > - end2 = r; > - } > - else > + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) > + { > + if (r2 == NULL) > + r2 = r; > + end2 = r; > + continue; > + } > # endif > - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, > - (void *) (l_addr + r->r_offset), skip_ifunc); > + elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg, > + skip_ifunc); OK. We are in the non-lazy case as expected. > +# if defined SHARED && !defined RTLD_BOOTSTRAP > + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT > + && GLRO(dl_naudit) > 0) > + { > + struct link_map *sym_map > + = RESOLVE_MAP (map, scope, &sym, > + (struct r_found_version *) NULL, > + ELF_MACHINE_JMP_SLOT); > + if (sym != NULL) > + _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map); OK. Again do the symbol binding auditing for immediate binding. > + } > +# endif > + } > > # ifdef ELF_MACHINE_IRELATIVE > if (r2 != NULL) > diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c > index 1077458c9d..a5edd438f9 100644 > --- a/elf/sotruss-lib.c > +++ b/elf/sotruss-lib.c > @@ -16,6 +16,7 @@ > License along with the GNU C Library; if not, see > <https://www.gnu.org/licenses/>. */ > > +#include <err.h> > #include <error.h> > #include <fcntl.h> > #include <stdio.h> > @@ -231,6 +232,12 @@ uintptr_t > la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook, > uintptr_t *defcook, unsigned int *flags, const char *symname) > { > + if (*flags & LA_SYMB_NOPLTENTER) > + warnx ("cannot trace PLT enter (bind-now enabled)"); OK. Awesome! :-) > + > + if (do_exit && *flags & LA_SYMB_NOPLTEXIT) > + warnx ("cannot trace PLT exit (bind-now enabled)"); OK. > + > if (!do_exit) > *flags = LA_SYMB_NOPLTEXIT; > > diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c > new file mode 100644 > index 0000000000..2cdd3fb98b > --- /dev/null > +++ b/elf/tst-audit24a.c > @@ -0,0 +1,36 @@ > +/* DL_AUDIT test for la_symbind and bind-now. s/DL_AUDIT/LD_AUDIT/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <support/check.h> > +#include <support/support.h> > + > +int tst_audit24amod1_func1 (void); > +int tst_audit24amod1_func2 (void); > +int tst_audit24amod2_func1 (void); OK. Calling 3 DSO functions with args. > + > +int > +do_test (void) > +{ > + TEST_COMPARE (tst_audit24amod1_func1 (), 1); > + TEST_COMPARE (tst_audit24amod1_func2 (), 2); > + TEST_COMPARE (tst_audit24amod2_func1 (), 10); > + > + return 0; > +} > + > +#include <support/test-driver.c> > diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c > new file mode 100644 > index 0000000000..c287372e32 > --- /dev/null > +++ b/elf/tst-audit24amod1.c > @@ -0,0 +1,31 @@ > +/* Modules used by tst-audit24a. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdlib.h> > + > +_Noreturn int > +tst_audit24amod1_func1 (void) > +{ > + abort (); OK. Calls abort. Needs redirecting. > +} > + > +int > +tst_audit24amod1_func2 (void) > +{ > + return 2; OK. > +} > diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c > new file mode 100644 > index 0000000000..938c71dc29 > --- /dev/null > +++ b/elf/tst-audit24amod2.c > @@ -0,0 +1,25 @@ > +/* Modules used by tst-audit24a. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdlib.h> > + > +_Noreturn int > +tst_audit24amod2_func1 (void) > +{ > + abort (); OK. Function aborts. Needs redirecting. > +} > diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c > new file mode 100644 > index 0000000000..82478ed8f9 > --- /dev/null > +++ b/elf/tst-audit24b.c > @@ -0,0 +1,37 @@ > +/* DL_AUDIT test for la_symbind and bind-now. s/DL_AUDIT/LD_AUDIT/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +/* This is similar to tst-audit24a, with the difference this modules > + does not have the .gnu.version section header. */ > + > +#include <support/check.h> > +#include <support/support.h> > + > +int tst_audit24bmod1_func1 (void); > +int tst_audit24bmod1_func2 (void); > + > +int > +do_test (void) > +{ > + TEST_COMPARE (tst_audit24bmod1_func1 (), 1); > + TEST_COMPARE (tst_audit24bmod1_func2 (), 2); OK. Second test. Call two DSO functions. > + > + return 0; > +} > + > +#include <support/test-driver.c> > diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c > new file mode 100644 > index 0000000000..5fa4611918 > --- /dev/null > +++ b/elf/tst-audit24bmod1.c > @@ -0,0 +1,31 @@ > +/* Modules used by tst-audit24c. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +int tst_audit24bmod2_func1 (void); > + > +int > +tst_audit24bmod1_func1 (void) > +{ > + return -1; > +} > + > +int > +tst_audit24bmod1_func2 (void) > +{ > + return tst_audit24bmod2_func1 (); OK. fun2 calls func1 in dependent DSO. > +} > diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c > new file mode 100644 > index 0000000000..d469e70a41 > --- /dev/null > +++ b/elf/tst-audit24bmod2.c > @@ -0,0 +1,23 @@ > +/* Modules used by tst-audit24b. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +int > +tst_audit24bmod2_func1 (void) > +{ > + return -1; OK. > +} > diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c > new file mode 100644 > index 0000000000..46ed328756 > --- /dev/null > +++ b/elf/tst-audit24c.c > @@ -0,0 +1,2 @@ > +/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now */ > +#include "tst-audit24a.c" OK. > diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c > new file mode 100644 > index 0000000000..1c89e4cb83 > --- /dev/null > +++ b/elf/tst-audit24d.c > @@ -0,0 +1,36 @@ > +/* DL_AUDIT test for la_symbind and bind-now. s/DL_AUDIT/LD_AUDIT/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <support/check.h> > +#include <support/support.h> > + > +int tst_audit24dmod1_func1 (void); > +int tst_audit24dmod1_func2 (void); > +int tst_audit24dmod2_func1 (void); > + > +int > +do_test (void) > +{ > + TEST_COMPARE (tst_audit24dmod1_func1 (), 1); > + TEST_COMPARE (tst_audit24dmod1_func2 (), 32); > + TEST_COMPARE (tst_audit24dmod2_func1 (), 10); OK. Call functions in 2 DSOs. > + > + return 0; > +} > + > +#include <support/test-driver.c> > diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c > new file mode 100644 > index 0000000000..3ff2218c96 > --- /dev/null > +++ b/elf/tst-audit24dmod1.c > @@ -0,0 +1,33 @@ > +/* Modules used by tst-audit24d. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdlib.h> > + > +int tst_audit24dmod3_func1 (void); > + > +_Noreturn int > +tst_audit24dmod1_func1 (void) > +{ > + abort (); OK. Function aborts. Needs redirection. > +} > + > +int > +tst_audit24dmod1_func2 (void) > +{ > + return 2 + tst_audit24dmod3_func1 ();; s/;;/;/g OK. Calls 3rd DSO. > +} > diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c > new file mode 100644 > index 0000000000..03fe938128 > --- /dev/null > +++ b/elf/tst-audit24dmod2.c > @@ -0,0 +1,28 @@ > +/* Module for tst-audit24d. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdlib.h> > + > +int tst_audit24dmod4_func1 (void); > + > +_Noreturn int > +tst_audit24dmod2_func1 (void) > +{ > + tst_audit24dmod4_func1 (); > + abort (); OK. Calls 4th DSO and *then* aborts. > +} > diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c > new file mode 100644 > index 0000000000..106d517d28 > --- /dev/null > +++ b/elf/tst-audit24dmod3.c > @@ -0,0 +1,31 @@ > +/* Module for tst-audit24d. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdlib.h> > + > +_Noreturn int > +tst_audit24dmod3_func1 (void) > +{ > + abort (); > +} > + > +int > +tst_audit24dmod3_func2 (void) > +{ > + return 4; > +} OK. > diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c > new file mode 100644 > index 0000000000..1da3b46917 > --- /dev/null > +++ b/elf/tst-audit24dmod4.c > @@ -0,0 +1,25 @@ > +/* Module for tst-audit24d. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdlib.h> > + > +_Noreturn int > +tst_audit24dmod4_func1 (void) > +{ > + abort (); > +} OK. > diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c > new file mode 100644 > index 0000000000..3476069353 > --- /dev/null > +++ b/elf/tst-audit25a.c > @@ -0,0 +1,129 @@ > +/* Check DT_AUDIT and LD_BIND_NOW. s/DT_AUDIT/LD_AUDIT/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <array_length.h> > +#include <errno.h> > +#include <getopt.h> > +#include <limits.h> > +#include <inttypes.h> > +#include <string.h> > +#include <stdlib.h> > +#include <support/capture_subprocess.h> > +#include <support/check.h> > +#include <support/xstdio.h> > +#include <support/support.h> > +#include <sys/auxv.h> > + > +static int restart; > +#define CMDLINE_OPTIONS \ > + { "restart", no_argument, &restart, 1 }, > + > +void tst_audit25mod1_func1 (void); > +void tst_audit25mod1_func2 (void); > +void tst_audit25mod2_func1 (void); > +void tst_audit25mod2_func2 (void); > + > +static int > +handle_restart (void) > +{ > + tst_audit25mod1_func1 (); > + tst_audit25mod1_func2 (); > + tst_audit25mod2_func1 (); > + tst_audit25mod2_func2 (); > + > + return 0; > +} > + > +static inline bool > +startswith (const char *str, const char *pre) > +{ > + size_t lenpre = strlen (pre); > + size_t lenstr = strlen (str); > + return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0; > +} > + > +static int > +do_test (int argc, char *argv[]) > +{ > + /* We must have either: > + - One our fource parameters left if called initially: s/One our fource/One or four/g > + + path to ld.so optional > + + "--library-path" optional > + + the library path optional > + + the application name */ > + > + if (restart) > + return handle_restart (); > + > + setenv ("LD_AUDIT", "tst-auditmod25.so", 0); > + > + char *spargv[9]; > + int i = 0; > + for (; i < argc - 1; i++) > + spargv[i] = argv[i + 1]; > + spargv[i++] = (char *) "--direct"; > + spargv[i++] = (char *) "--restart"; > + spargv[i] = NULL; > + TEST_VERIFY_EXIT (i < array_length (spargv)); > + > + { > + struct support_capture_subprocess result > + = support_capture_subprogram (spargv[0], spargv); > + support_capture_subprocess_check (&result, "tst-audit25a", 0, > + sc_allow_stderr); OK. Call ourselves again. > + > + /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with > + -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to > + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ > + TEST_COMPARE_STRING (result.err.buffer, > + "la_symbind: tst_audit25mod3_func1 1\n" > + "la_symbind: tst_audit25mod1_func1 0\n" > + "la_symbind: tst_audit25mod1_func2 0\n" > + "la_symbind: tst_audit25mod2_func1 0\n" > + "la_symbind: tst_audit25mod4_func1 0\n" > + "la_symbind: tst_audit25mod2_func2 0\n"); > + > + support_capture_subprocess_free (&result); > + } > + > + { > + setenv ("LD_BIND_NOW", "1", 0); > + struct support_capture_subprocess result > + = support_capture_subprogram (spargv[0], spargv); > + support_capture_subprocess_check (&result, "tst-audit25a", 0, > + sc_allow_stderr); OK. > + > + /* With LD_BIND_NOW all symbols are expected to have > + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution > + order is done in breadth-first order. */ > + TEST_COMPARE_STRING (result.err.buffer, > + "la_symbind: tst_audit25mod4_func1 1\n" > + "la_symbind: tst_audit25mod3_func1 1\n" > + "la_symbind: tst_audit25mod1_func1 1\n" > + "la_symbind: tst_audit25mod2_func1 1\n" > + "la_symbind: tst_audit25mod1_func2 1\n" > + "la_symbind: tst_audit25mod2_func2 1\n"); > + > + support_capture_subprocess_free (&result); > + } > + > + return 0; > +} > + > +#define TEST_FUNCTION_ARGV do_test > +#include <support/test-driver.c> > diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c > new file mode 100644 > index 0000000000..8bf98bc7fd > --- /dev/null > +++ b/elf/tst-audit25b.c > @@ -0,0 +1,128 @@ > +/* Check DT_AUDIT and LD_BIND_NOW. s/DT_AUDIT/LD_AUDIT/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <errno.h> > +#include <getopt.h> > +#include <limits.h> > +#include <inttypes.h> > +#include <string.h> > +#include <stdlib.h> > +#include <support/capture_subprocess.h> > +#include <support/check.h> > +#include <support/xstdio.h> > +#include <support/support.h> > +#include <sys/auxv.h> > + > +static int restart; > +#define CMDLINE_OPTIONS \ > + { "restart", no_argument, &restart, 1 }, > + > +void tst_audit25mod1_func1 (void); > +void tst_audit25mod1_func2 (void); > +void tst_audit25mod2_func1 (void); > +void tst_audit25mod2_func2 (void); > + > +static int > +handle_restart (void) > +{ > + tst_audit25mod1_func1 (); > + tst_audit25mod1_func2 (); > + tst_audit25mod2_func1 (); > + tst_audit25mod2_func2 (); > + > + return 0; > +} > + > +static inline bool > +startswith (const char *str, const char *pre) > +{ > + size_t lenpre = strlen (pre); > + size_t lenstr = strlen (str); > + return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0; > +} > + > +static int > +do_test (int argc, char *argv[]) > +{ > + /* We must have either: > + - One our fource parameters left if called initially: s/One our fource/One or four/g > + + path to ld.so optional > + + "--library-path" optional > + + the library path optional > + + the application name */ > + > + if (restart) > + return handle_restart (); > + > + setenv ("LD_AUDIT", "tst-auditmod25.so", 0); > + > + char *spargv[9]; > + int i = 0; > + for (; i < argc - 1; i++) > + spargv[i] = argv[i + 1]; > + spargv[i++] = (char *) "--direct"; > + spargv[i++] = (char *) "--restart"; > + spargv[i] = NULL; > + > + { > + struct support_capture_subprocess result > + = support_capture_subprogram (spargv[0], spargv); > + support_capture_subprocess_check (&result, "tst-audit25a", 0, > + sc_allow_stderr); OK. > + > + /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but > + tst-audit25mod2 is built with -Wl,z,lazy. So only s/,z,/,-z,/g > + tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not > + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ > + TEST_COMPARE_STRING (result.err.buffer, > + "la_symbind: tst_audit25mod3_func1 1\n" > + "la_symbind: tst_audit25mod1_func1 1\n" > + "la_symbind: tst_audit25mod2_func1 1\n" > + "la_symbind: tst_audit25mod1_func2 1\n" > + "la_symbind: tst_audit25mod2_func2 1\n" > + "la_symbind: tst_audit25mod4_func1 0\n"); > + > + support_capture_subprocess_free (&result); > + } > + > + { > + setenv ("LD_BIND_NOW", "1", 0); > + struct support_capture_subprocess result > + = support_capture_subprogram (spargv[0], spargv); > + support_capture_subprocess_check (&result, "tst-audit25a", 0, > + sc_allow_stderr); > + > + /* With LD_BIND_NOW all symbols are expected to have > + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution > + order is done in breadth-first order. */ OK. > + TEST_COMPARE_STRING (result.err.buffer, > + "la_symbind: tst_audit25mod4_func1 1\n" > + "la_symbind: tst_audit25mod3_func1 1\n" > + "la_symbind: tst_audit25mod1_func1 1\n" > + "la_symbind: tst_audit25mod2_func1 1\n" > + "la_symbind: tst_audit25mod1_func2 1\n" > + "la_symbind: tst_audit25mod2_func2 1\n"); > + > + support_capture_subprocess_free (&result); > + } > + > + return 0; > +} > + > +#define TEST_FUNCTION_ARGV do_test > +#include <support/test-driver.c> > diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c > new file mode 100644 > index 0000000000..3cff8cc688 > --- /dev/null > +++ b/elf/tst-audit25mod1.c > @@ -0,0 +1,30 @@ > +/* Modules used by tst-audit25. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +void tst_audit25mod3_func1 (void); > + > +void > +tst_audit25mod1_func1 (void) > +{ > + tst_audit25mod3_func1 (); > +} > + > +void > +tst_audit25mod1_func2 (void) > +{ > +} OK. > diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c > new file mode 100644 > index 0000000000..5e40555fa9 > --- /dev/null > +++ b/elf/tst-audit25mod2.c > @@ -0,0 +1,30 @@ > +/* Modules used by tst-audit25. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +void tst_audit25mod4_func1 (void); > + > +void > +tst_audit25mod2_func1 (void) > +{ > + tst_audit25mod4_func1 (); > +} > + > +void > +tst_audit25mod2_func2 (void) > +{ > +} OK. > diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c > new file mode 100644 > index 0000000000..e35ed6a1da > --- /dev/null > +++ b/elf/tst-audit25mod3.c > @@ -0,0 +1,22 @@ > +/* Modules used by tst-audit25. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +void > +tst_audit25mod3_func1 (void) > +{ > +} OK. > diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c > new file mode 100644 > index 0000000000..c3118b6368 > --- /dev/null > +++ b/elf/tst-audit25mod4.c > @@ -0,0 +1,22 @@ > +/* Modules used by tst-audit25. s/Modules/Module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +void > +tst_audit25mod4_func1 (void) > +{ > +} OK. > diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h > new file mode 100644 > index 0000000000..e34c53df5e > --- /dev/null > +++ b/elf/tst-auditmod24.h > @@ -0,0 +1,29 @@ > +/* Auxiliary functions for tst-audit24x. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#ifndef _TST_AUDITMOD24_H > +#define _TST_AUDITMOD24_H > + > +static void > +check_symbind_flags (unsigned int flags) Would suggest calling it "test_symbind_flags" since this is testing a specific condition of the test and aborting if not met. > +{ > + if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0) > + abort (); OK. Abort if none of the flags are set. > +} > + > +#endif > diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c > new file mode 100644 > index 0000000000..a4838b3e05 > --- /dev/null > +++ b/elf/tst-auditmod24a.c > @@ -0,0 +1,114 @@ > +/* Audit modules for tst-audit24a. s/modules/module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <link.h> > +#include <inttypes.h> > +#include <stdlib.h> > +#include <string.h> > +#include <tst-auditmod24.h> > + > +#define AUDIT24_COOKIE 0x1 > +#define AUDIT24MOD1_COOKIE 0x2 > +#define AUDIT24MOD2_COOKIE 0x3 > + > +#ifndef TEST_NAME > +# define TEST_NAME "tst-audit24a" > +#endif > +#ifndef TEST_MOD > +# define TEST_MOD TEST_NAME > +#endif > +#ifndef TEST_FUNC > +# define TEST_FUNC "tst_audit24a" > +#endif > + > +unsigned int > +la_version (unsigned int version) > +{ > + return LAV_CURRENT; > +} > + > +unsigned int > +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) > +{ > + const char *p = strrchr (map->l_name, '/'); > + const char *l_name = p == NULL ? TEST_NAME : p + 1; > + > + uintptr_t ck = -1; > + if (strcmp (l_name, TEST_MOD "mod1.so") == 0) > + ck = AUDIT24MOD1_COOKIE; > + else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) > + ck = AUDIT24MOD2_COOKIE; > + else if (strcmp (l_name, TEST_NAME) == 0) > + ck = AUDIT24_COOKIE; > + > + *cookie = ck; > + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; OK. > +} > + > +static int > +tst_func1 (void) > +{ > + return 1; > +} > + > +static int > +tst_func2 (void) > +{ > + return 10; > +} OK. Define two safety functions to use to avoid abort()s in the actual implementations. > + > +#if __ELF_NATIVE_CLASS == 64 > +uintptr_t > +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#else > +uintptr_t > +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#endif > +{ > + if (*refcook == AUDIT24_COOKIE) > + { > + if (*defcook == AUDIT24MOD1_COOKIE) > + { > + /* Check if bind-now symbols are advertised to not call the PLT > + hooks. */ > + check_symbind_flags (*flags); > + > + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) > + return (uintptr_t) tst_func1; > + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) > + return sym->st_value; > + abort (); > + } > + if (*defcook == AUDIT24MOD2_COOKIE > + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) > + { > + check_symbind_flags (*flags); > + > + return (uintptr_t) tst_func2; > + } > + > + /* malloc functions. */ > + return sym->st_value; > + } > + > + abort (); OK. > +} > diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c > new file mode 100644 > index 0000000000..aefac8ced4 > --- /dev/null > +++ b/elf/tst-auditmod24b.c > @@ -0,0 +1,104 @@ > +/* Audit modules for tst-audit24b. s/modules/module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <link.h> > +#include <inttypes.h> > +#include <stdlib.h> > +#include <string.h> > +#include <tst-auditmod24.h> > + > +#define TEST_NAME "tst-audit24b" > +#define TEST_FUNC "tst_audit24b" > + > +#define AUDIT24_COOKIE 0x1 > +#define AUDIT24MOD1_COOKIE 0x2 > +#define AUDIT24MOD2_COOKIE 0x3 > + > +unsigned int > +la_version (unsigned int version) > +{ > + return LAV_CURRENT; > +} > + > +unsigned int > +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) > +{ > + const char *p = strrchr (map->l_name, '/'); > + const char *l_name = p == NULL ? TEST_NAME : p + 1; > + > + uintptr_t ck = -1; > + if (strcmp (l_name, TEST_NAME "mod1.so") == 0) > + ck = AUDIT24MOD1_COOKIE; > + else if (strcmp (l_name, TEST_NAME "mod2.so") == 0) > + ck = AUDIT24MOD2_COOKIE; > + else if (strcmp (l_name, TEST_NAME) == 0) > + ck = AUDIT24_COOKIE; > + > + *cookie = ck; > + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; OK. > +} > + > +static int > +tst_func1 (void) > +{ > + return 1; > +} > + > +static int > +tst_func2 (void) > +{ > + return 2; > +} OK. Define two safe functions. > + > +#if __ELF_NATIVE_CLASS == 64 > +uintptr_t > +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#else > +uintptr_t > +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#endif > +{ > + if (*refcook == AUDIT24_COOKIE) > + { > + if (*defcook == AUDIT24MOD1_COOKIE) > + { > + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) > + return (uintptr_t) tst_func1; OK. > + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) > + return sym->st_value; > + abort (); > + } > + /* malloc functions. */ > + return sym->st_value; > + } > + else if (*refcook == AUDIT24MOD1_COOKIE) > + { > + if (*defcook == AUDIT24MOD2_COOKIE > + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) > + { > + check_symbind_flags (*flags); > + return (uintptr_t) tst_func2; OK. > + } > + } > + > + abort (); > +} > diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c > new file mode 100644 > index 0000000000..67e62c9d33 > --- /dev/null > +++ b/elf/tst-auditmod24c.c > @@ -0,0 +1,3 @@ > +#define TEST_NAME "tst-audit24c" > +#define TEST_MOD "tst-audit24a" > +#include "tst-auditmod24a.c" OK. > diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c > new file mode 100644 > index 0000000000..a49f00ef17 > --- /dev/null > +++ b/elf/tst-auditmod24d.c > @@ -0,0 +1,120 @@ > +/* Audit module for tst-audit24d. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <link.h> > +#include <inttypes.h> > +#include <stdlib.h> > +#include <string.h> > +#include <tst-auditmod24.h> > + > +#define AUDIT24_COOKIE 0x0 > +#define AUDIT24MOD1_COOKIE 0x1 > +#define AUDIT24MOD2_COOKIE 0x2 > +#define AUDIT24MOD3_COOKIE 0x3 > +#define AUDIT24MOD4_COOKIE 0x4 > + > +unsigned int > +la_version (unsigned int version) > +{ > + return LAV_CURRENT; OK. > +} > + > +unsigned int > +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) > +{ > + const char *p = strrchr (map->l_name, '/'); > + const char *l_name = p == NULL ? "tst-audit24d" : p + 1; > + > + uintptr_t ck = -1; > + if (strcmp (l_name, "tst-audit24dmod1.so") == 0) > + ck = AUDIT24MOD1_COOKIE; > + else if (strcmp (l_name, "tst-audit24dmod2.so") == 0) > + ck = AUDIT24MOD2_COOKIE; > + else if (strcmp (l_name, "tst-audit24dmod3.so") == 0) > + ck = AUDIT24MOD3_COOKIE; > + else if (strcmp (l_name, "tst-audit24dmod.so") == 0) > + ck = AUDIT24MOD4_COOKIE; > + else if (strcmp (l_name, "tst-audit24d") == 0) > + ck = AUDIT24_COOKIE; > + > + *cookie = ck; > + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; OK. > +} > + > +static int > +tst_audit24dmod1_func1 (void) > +{ > + return 1; > +} > + > +static int > +tst_audit24dmod2_func1 (void) > +{ > + return 10; > +} > + > +static int > +tst_audit24dmod3_func1 (void) > +{ > + return 30; > +} OK. > + > +#include <stdio.h> > + > +#if __ELF_NATIVE_CLASS == 64 > +uintptr_t > +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#else > +uintptr_t > +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#endif > +{ > + if (*refcook == AUDIT24_COOKIE) > + { > + if (*defcook == AUDIT24MOD1_COOKIE) > + { > + if (strcmp (symname, "tst_audit24dmod1_func1") == 0) > + return (uintptr_t) tst_audit24dmod1_func1; > + else if (strcmp (symname, "tst_audit24dmod1_func2") == 0) > + return sym->st_value; > + abort (); > + } > + if (*defcook == AUDIT24MOD2_COOKIE > + && (strcmp (symname, "tst_audit24dmod2_func1") == 0)) > + return (uintptr_t) tst_audit24dmod2_func1; > + > + /* malloc functions. */ > + return sym->st_value; > + } > + else if (*refcook == AUDIT24MOD1_COOKIE) > + { > + if (*defcook == AUDIT24MOD3_COOKIE > + && strcmp (symname, "tst_audit24dmod3_func1") == 0) > + { > + check_symbind_flags (*flags); > + > + return (uintptr_t) tst_audit24dmod3_func1; > + } > + } > + > + abort (); > +} OK. > diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c > new file mode 100644 > index 0000000000..526f5c54bc > --- /dev/null > +++ b/elf/tst-auditmod25.c > @@ -0,0 +1,79 @@ > +/* Audit modules for tst-audit25a. s/modules/module/g > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <link.h> > +#include <inttypes.h> > +#include <stdlib.h> > +#include <string.h> > +#include <stdio.h> > + > +#define AUDIT25_COOKIE 0x1 > +#define AUDIT25MOD1_COOKIE 0x2 > +#define AUDIT25MOD2_COOKIE 0x3 > +#define AUDIT25MOD3_COOKIE 0x2 > +#define AUDIT25MOD4_COOKIE 0x3 > + > +#define TEST_NAME "tst-audit25" > +#define TEST_MOD "tst-audit25" > +#define TEST_FUNC "tst_audit25" > + > +unsigned int > +la_version (unsigned int version) > +{ > + return LAV_CURRENT; > +} > + > +unsigned int > +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) > +{ > + const char *p = strrchr (map->l_name, '/'); > + const char *l_name = p == NULL ? TEST_NAME : p + 1; > + > + uintptr_t ck = -1; > + if (strcmp (l_name, TEST_MOD "mod1.so") == 0) > + ck = AUDIT25MOD1_COOKIE; > + else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) > + ck = AUDIT25MOD2_COOKIE; > + else if (strcmp (l_name, TEST_MOD "mod3.so") == 0) > + ck = AUDIT25MOD3_COOKIE; > + else if (strcmp (l_name, TEST_MOD "mod4.so") == 0) > + ck = AUDIT25MOD4_COOKIE; > + else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) > + ck = AUDIT25_COOKIE; > + > + *cookie = ck; > + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; OK. > +} > + > +#if __ELF_NATIVE_CLASS == 64 > +uintptr_t > +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#else > +uintptr_t > +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, > + uintptr_t *refcook, uintptr_t *defcook, > + unsigned int *flags, const char *symname) > +#endif > +{ > + if (*refcook != -1 && *defcook != -1) > + fprintf (stderr, "la_symbind: %s %u\n", symname, > + *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0); OK. > + return sym->st_value; > +} > diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h > index 7460c0596a..95bcfc1cc1 100644 > --- a/sysdeps/generic/dl-lookupcfg.h > +++ b/sysdeps/generic/dl-lookupcfg.h > @@ -26,3 +26,6 @@ > #define DL_FIXUP_VALUE_CODE_ADDR(value) (value) > #define DL_FIXUP_VALUE_ADDR(value) (value) > #define DL_FIXUP_ADDR_VALUE(addr) (addr) > +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) > +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ > + (*value) = st_value; OK. > diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h > index 97061bdf9f..2ebe7901c0 100644 > --- a/sysdeps/generic/ldsodefs.h > +++ b/sysdeps/generic/ldsodefs.h > @@ -1431,7 +1431,10 @@ void _dl_audit_objclose (struct link_map *l) > /* Call the la_preinit from the audit modules for the link_map L. */ > void _dl_audit_preinit (struct link_map *l); > > -/* Call the la_symbind{32,64} from the audit modules for the link_map L. */ > +/* Call the la_symbind{32,64} from the audit modules for the link_map L. If > + RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set > + the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling > + la_symbind{32,64}. */ OK. > void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, > const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, > lookup_t result) > diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h > index 5d381147c0..8da2412fea 100644 > --- a/sysdeps/hppa/dl-lookupcfg.h > +++ b/sysdeps/hppa/dl-lookupcfg.h > @@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map); > #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip) > #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) > #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) > +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) > +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ > + (*value) = *(struct fdesc *) (st_value) OK. > diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h > index b8ab1bba15..3df3116b31 100644 > --- a/sysdeps/ia64/dl-lookupcfg.h > +++ b/sysdeps/ia64/dl-lookupcfg.h > @@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map); > > #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) > #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) > +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) > +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ > + (*value) = *(struct fdesc *) (st_value) OK. > diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h > new file mode 100644 > index 0000000000..25abcc1d12 > --- /dev/null > +++ b/sysdeps/powerpc/dl-lookupcfg.h > @@ -0,0 +1,39 @@ > +/* Configuration of lookup functions. PowerPC version. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#define DL_FIXUP_VALUE_TYPE ElfW(Addr) > +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) > +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) > +#define DL_FIXUP_VALUE_ADDR(value) (value) > +#define DL_FIXUP_ADDR_VALUE(addr) (addr) > +#if __WORDSIZE == 64 && _CALL_ELF == 1 > +/* We need to correctly set the audit modules value for bind-now. */ > +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \ > + (((Elf64_FuncDesc *)(addr))->fd_func) > +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ > + ({ \ > + Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value); \ > + opd->fd_func = (st_value); \ > + if ((new_value) != (uintptr_t) (st_value)) \ > + opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc; \ OK. > + }) > +#else > +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) > +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ > + (*value) = st_value; OK. > +#endif
On 01/02/2022 03:06, Carlos O'Donell wrote: > On 1/25/22 13:36, Adhemerval Zanella wrote: >> The audit symbind callback is not called for binaries built with >> -Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks >> (plt_enter and plt_exit) since this will would change the expected > > s/will would/would/g Ack. > >> program semantic (where no PTL is expected) and would incur in > > s/semantic/semantics/g > s/PTL/PLT/g > s/incur in/have/g > Ack. >> performance implications (such as for BZ#15533). >> >> LAV_CURRENT is also bumped to indicate the audit ABI change (where >> la_symbind flags are set by the loader to indicate no possible PTL > > s/PTL/PLT/g Ack. > >> trace). >> >> To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind >> requires to know whether bind-now is used so the symbol value is >> updated to function text segment instead of the OPD (for lazy binding >> this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve). >> >> Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, >> powerpc64-linux-gnu. > > Please post v13 and I'll ack that for glibc 2.35. > >> --- >> NEWS | 4 + >> bits/link_lavcurrent.h | 2 +- >> elf/Makefile | 89 ++++++++++++++++++++++- >> elf/dl-audit.c | 58 +++++++++------ >> elf/do-rel.h | 57 +++++++++++---- >> elf/sotruss-lib.c | 7 ++ >> elf/tst-audit24a.c | 36 +++++++++ >> elf/tst-audit24amod1.c | 31 ++++++++ >> elf/tst-audit24amod2.c | 25 +++++++ >> elf/tst-audit24b.c | 37 ++++++++++ >> elf/tst-audit24bmod1.c | 31 ++++++++ >> elf/tst-audit24bmod2.c | 23 ++++++ >> elf/tst-audit24c.c | 2 + >> elf/tst-audit24d.c | 36 +++++++++ >> elf/tst-audit24dmod1.c | 33 +++++++++ >> elf/tst-audit24dmod2.c | 28 +++++++ >> elf/tst-audit24dmod3.c | 31 ++++++++ >> elf/tst-audit24dmod4.c | 25 +++++++ >> elf/tst-audit25a.c | 129 +++++++++++++++++++++++++++++++++ >> elf/tst-audit25b.c | 128 ++++++++++++++++++++++++++++++++ >> elf/tst-audit25mod1.c | 30 ++++++++ >> elf/tst-audit25mod2.c | 30 ++++++++ >> elf/tst-audit25mod3.c | 22 ++++++ >> elf/tst-audit25mod4.c | 22 ++++++ >> elf/tst-auditmod24.h | 29 ++++++++ >> elf/tst-auditmod24a.c | 114 +++++++++++++++++++++++++++++ >> elf/tst-auditmod24b.c | 104 ++++++++++++++++++++++++++ >> elf/tst-auditmod24c.c | 3 + >> elf/tst-auditmod24d.c | 120 ++++++++++++++++++++++++++++++ >> elf/tst-auditmod25.c | 79 ++++++++++++++++++++ >> sysdeps/generic/dl-lookupcfg.h | 3 + >> sysdeps/generic/ldsodefs.h | 5 +- >> sysdeps/hppa/dl-lookupcfg.h | 3 + >> sysdeps/ia64/dl-lookupcfg.h | 3 + >> sysdeps/powerpc/dl-lookupcfg.h | 39 ++++++++++ >> 35 files changed, 1379 insertions(+), 39 deletions(-) >> create mode 100644 elf/tst-audit24a.c >> create mode 100644 elf/tst-audit24amod1.c >> create mode 100644 elf/tst-audit24amod2.c >> create mode 100644 elf/tst-audit24b.c >> create mode 100644 elf/tst-audit24bmod1.c >> create mode 100644 elf/tst-audit24bmod2.c >> create mode 100644 elf/tst-audit24c.c >> create mode 100644 elf/tst-audit24d.c >> create mode 100644 elf/tst-audit24dmod1.c >> create mode 100644 elf/tst-audit24dmod2.c >> create mode 100644 elf/tst-audit24dmod3.c >> create mode 100644 elf/tst-audit24dmod4.c >> create mode 100644 elf/tst-audit25a.c >> create mode 100644 elf/tst-audit25b.c >> create mode 100644 elf/tst-audit25mod1.c >> create mode 100644 elf/tst-audit25mod2.c >> create mode 100644 elf/tst-audit25mod3.c >> create mode 100644 elf/tst-audit25mod4.c >> create mode 100644 elf/tst-auditmod24.h >> create mode 100644 elf/tst-auditmod24a.c >> create mode 100644 elf/tst-auditmod24b.c >> create mode 100644 elf/tst-auditmod24c.c >> create mode 100644 elf/tst-auditmod24d.c >> create mode 100644 elf/tst-auditmod25.c >> create mode 100644 sysdeps/powerpc/dl-lookupcfg.h >> >> diff --git a/NEWS b/NEWS >> index a9f25d3225..c0f8932f84 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -158,6 +158,10 @@ Deprecated and removed features, and other changes affecting compatibility: >> been removed. There are widely-deployed out-of-process alternatives for >> catching coredumps and backtraces. >> >> +* The audit module interface version LAV_CURRENT is increased to enable >> + proper bind-now support. The loader now advertises on the la_symbind > > s/on/via/g Ack. > >> + flags that PLT trace is not possible. >> + >> Changes to build and runtime requirements: >> >> [Add changes to build and runtime requirements here] >> diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h >> index 7bfa4b9f4e..a852d41302 100644 >> --- a/bits/link_lavcurrent.h >> +++ b/bits/link_lavcurrent.h >> @@ -22,4 +22,4 @@ >> #endif >> >> /* Version numbers for la_version handshake interface. */ >> -#define LAV_CURRENT 1 >> +#define LAV_CURRENT 2 > > OK. New version. > >> diff --git a/elf/Makefile b/elf/Makefile >> index 7d01b71f6a..b9edcccb82 100644 >> --- a/elf/Makefile >> +++ b/elf/Makefile >> @@ -379,6 +379,12 @@ tests += \ >> tst-audit21 \ >> tst-audit22 \ >> tst-audit23 \ >> + tst-audit24a \ >> + tst-audit24b \ >> + tst-audit24c \ >> + tst-audit24d \ >> + tst-audit25a \ >> + tst-audit25b \ > > OK. New tests. > >> tst-auditmany \ >> tst-auxobj \ >> tst-auxobj-dlopen \ >> @@ -676,6 +682,18 @@ modules-names = \ >> tst-audit18mod \ >> tst-audit19bmod \ >> tst-audit23mod \ >> + tst-audit24amod1 \ >> + tst-audit24amod2 \ >> + tst-audit24bmod1 \ >> + tst-audit24bmod2 \ >> + tst-audit24dmod1 \ >> + tst-audit24dmod2 \ >> + tst-audit24dmod3 \ >> + tst-audit24dmod4 \ >> + tst-audit25mod1 \ >> + tst-audit25mod2 \ >> + tst-audit25mod3 \ >> + tst-audit25mod4 \ > > OK. New DSOs. > >> tst-auditlogmod-1 \ >> tst-auditlogmod-2 \ >> tst-auditlogmod-3 \ >> @@ -701,6 +719,11 @@ modules-names = \ >> tst-auditmod21b \ >> tst-auditmod22 \ >> tst-auditmod23 \ >> + tst-auditmod24a \ >> + tst-auditmod24b \ >> + tst-auditmod24c \ >> + tst-auditmod24d \ >> + tst-auditmod25 \ > > OK. New audit modules. > >> tst-auxvalmod \ >> tst-big-note-lib \ >> tst-deep1mod1 \ >> @@ -918,7 +941,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) >> >> # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special >> # rules. >> -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod >> +modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \ >> + tst-audit24bmod1 tst-audit24bmod2.so > > OK. Build them differently. > >> >> tests += $(tests-static) >> >> @@ -2151,6 +2175,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \ >> $(objpfx)tst-audit23mod.so >> tst-audit23-ARGS = -- $(host-test-program-cmd) >> >> +$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so >> +$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \ >> + $(objpfx)tst-audit24amod2.so >> +tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so >> +LDFLAGS-tst-audit24a = -Wl,-z,now > > OK. Ensure immmediate binding. > >> + >> +$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so >> +$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \ >> + $(objpfx)tst-audit24bmod2.so >> +$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so >> +# The test check if a library without .gnu.version correctly calls the > > s/check/checks/g Ack. > >> +# audit callbacks. So it uses an explicit link rule to avoid linking >> +# against libc.so. >> +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os >> + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \ >> + -Wl,-z,now >> + $(call after-link,$@.new) >> + mv -f $@.new $@ > > OK. > >> +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1) >> +$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os >> + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os >> + $(call after-link,$@.new) >> + mv -f $@.new $@ >> +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2) >> +tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so >> +LDFLAGS-tst-audit24b = -Wl,-z,now > > OK. > >> + >> +# Same as tst-audit24a, but tests LD_BIND_NOW >> +$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so >> +$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \ >> + $(objpfx)tst-audit24amod2.so >> +tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so > > OK. Immediate binding via env var. > >> +LDFLAGS-tst-audit24b = -Wl,-z,lazy > > OK. Testing lazy binding. > >> + >> +$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so >> +$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \ >> + $(objpfx)tst-audit24dmod2.so >> +$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so >> +LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now >> +$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so >> +LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy >> +tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so >> +LDFLAGS-tst-audit24d = -Wl,-z,lazy >> + >> +$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so >> +$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \ >> + $(objpfx)tst-audit25mod2.so \ >> + $(objpfx)tst-audit25mod3.so \ >> + $(objpfx)tst-audit25mod4.so >> +$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so >> +LDFLAGS-tst-audit25mod1.so = -Wl,-z,now >> +$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so >> +LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy >> +tst-audit25a-ARGS = -- $(host-test-program-cmd) >> + >> +$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so >> +$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ >> + $(objpfx)tst-audit25mod2.so \ >> + $(objpfx)tst-audit25mod3.so \ >> + $(objpfx)tst-audit25mod4.so >> +LDFLAGS-tst-audit25b = -Wl,-z,now >> +tst-audit25b-ARGS = -- $(host-test-program-cmd) >> + >> # tst-sonamemove links against an older implementation of the library. >> LDFLAGS-tst-sonamemove-linkmod1.so = \ >> -Wl,--version-script=tst-sonamemove-linkmod1.map \ >> diff --git a/elf/dl-audit.c b/elf/dl-audit.c >> index 715de53272..794bfd45cd 100644 >> --- a/elf/dl-audit.c >> +++ b/elf/dl-audit.c >> @@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, >> const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, >> lookup_t result) >> { >> - reloc_result->bound = result; >> - /* Compute index of the symbol entry in the symbol table of the DSO with the >> - definition. */ >> - reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result, >> - l_info[DT_SYMTAB])); >> + bool for_jmp_slot = reloc_result == NULL; > > OK. Check if we have relocation result. > >> + >> + /* Compute index of the symbol entry in the symbol table of the DSO >> + with the definition. */ >> + unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result, >> + l_info[DT_SYMTAB]); >> + if (!for_jmp_slot) >> + { >> + reloc_result->bound = result; >> + reloc_result->boundndx = boundndx; >> + } > > > OK. Need to guard reloc_result around !for_jmp_slot. > >> >> if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) >> { >> /* Set all bits since this symbol binding is not interesting. */ >> - reloc_result->enterexit = (1u << DL_NNS) - 1; >> + if (!for_jmp_slot) >> + reloc_result->enterexit = (1u << DL_NNS) - 1; > > OK. > >> return; >> } >> >> @@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, >> two bits. */ >> assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8); >> assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3); >> - reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; >> + uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; > > OK. > >> >> const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); >> >> unsigned int flags = 0; >> struct audit_ifaces *afct = GLRO(dl_audit); >> + uintptr_t new_value = (uintptr_t) sym.st_value; >> for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) >> { >> /* XXX Check whether both DSOs must request action or only one */ >> @@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, >> { >> if (afct->symbind != NULL) >> { > > OK. We have an auditor function to call. > >> - uintptr_t new_value = afct->symbind (&sym, >> - reloc_result->boundndx, >> - &l_state->cookie, >> - &result_state->cookie, >> - &flags, >> - strtab2 + defsym->st_name); >> + flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT >> + : 0; > > OK. Set incoming flags depending on for_jmp_slot. > >> + new_value = afct->symbind (&sym, boundndx, >> + &l_state->cookie, >> + &result_state->cookie, &flags, >> + strtab2 + defsym->st_name); >> if (new_value != (uintptr_t) sym.st_value) >> { >> flags |= LA_SYMB_ALTVALUE; >> - sym.st_value = new_value; >> + sym.st_value = for_jmp_slot >> + ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value; > > OK. > >> } >> } >> >> /* Remember the results for every audit library and store a summary >> in the first two bits. */ >> - reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER >> - | LA_SYMB_NOPLTEXIT); >> - reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER >> - | LA_SYMB_NOPLTEXIT)) >> - << ((cnt + 1) * 2)); >> + enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT); >> + enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) >> + << ((cnt + 1) * 2)); > > OK. > >> } >> else >> /* If the bind flags say this auditor is not interested, set the bits >> manually. */ >> - reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) >> - << ((cnt + 1) * 2)); >> + enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) >> + << ((cnt + 1) * 2)); > > OK. > >> afct = afct->next; >> } >> >> - reloc_result->flags = flags; >> - *value = DL_FIXUP_ADDR_VALUE (sym.st_value); >> + if (!for_jmp_slot) >> + { >> + reloc_result->enterexit = enterexit; >> + reloc_result->flags = flags; >> + } >> + >> + DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); > > OK. > >> } >> >> void >> diff --git a/elf/do-rel.h b/elf/do-rel.h >> index 0718badf83..60d5dce8f2 100644 >> --- a/elf/do-rel.h >> +++ b/elf/do-rel.h >> @@ -16,6 +16,8 @@ >> License along with the GNU C Library; if not, see >> <https://www.gnu.org/licenses/>. */ >> >> +#include <ldsodefs.h> >> + >> /* This file may be included twice, to define both >> `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ >> >> @@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], >> >> for (; r < end; ++r) >> { >> + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; >> + const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; >> + void *const r_addr_arg = (void *) (l_addr + r->r_offset); >> + const struct r_found_version *rversion = &map->l_versions[ndx]; >> #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP >> if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) >> { >> @@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], >> } >> #endif >> >> - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; >> - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], >> - &map->l_versions[ndx], >> - (void *) (l_addr + r->r_offset), skip_ifunc); >> + elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, >> + skip_ifunc); > > OK. We are in the non-lazy case. > >> +#if defined SHARED && !defined RTLD_BOOTSTRAP >> + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT >> + && GLRO(dl_naudit) > 0) >> + { >> + struct link_map *sym_map >> + = RESOLVE_MAP (map, scope, &sym, rversion, >> + ELF_MACHINE_JMP_SLOT); > > OK. Do the extra check at startup. > > >> + if (sym != NULL) >> + _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map); > > OK. Early immeidate binding for symbol. > >> + } >> +#endif >> } >> >> #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP >> @@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], >> else >> { >> for (; r < end; ++r) >> + { >> + const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; >> + void *const r_addr_arg = (void *) (l_addr + r->r_offset); >> # ifdef ELF_MACHINE_IRELATIVE >> - if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) >> - { >> - if (r2 == NULL) >> - r2 = r; >> - end2 = r; >> - } >> - else >> + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) >> + { >> + if (r2 == NULL) >> + r2 = r; >> + end2 = r; >> + continue; >> + } >> # endif >> - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, >> - (void *) (l_addr + r->r_offset), skip_ifunc); >> + elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg, >> + skip_ifunc); > > OK. We are in the non-lazy case as expected. > >> +# if defined SHARED && !defined RTLD_BOOTSTRAP >> + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT >> + && GLRO(dl_naudit) > 0) >> + { >> + struct link_map *sym_map >> + = RESOLVE_MAP (map, scope, &sym, >> + (struct r_found_version *) NULL, >> + ELF_MACHINE_JMP_SLOT); >> + if (sym != NULL) >> + _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map); > > OK. Again do the symbol binding auditing for immediate binding. > > >> + } >> +# endif >> + } >> >> # ifdef ELF_MACHINE_IRELATIVE >> if (r2 != NULL) >> diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c >> index 1077458c9d..a5edd438f9 100644 >> --- a/elf/sotruss-lib.c >> +++ b/elf/sotruss-lib.c >> @@ -16,6 +16,7 @@ >> License along with the GNU C Library; if not, see >> <https://www.gnu.org/licenses/>. */ >> >> +#include <err.h> >> #include <error.h> >> #include <fcntl.h> >> #include <stdio.h> >> @@ -231,6 +232,12 @@ uintptr_t >> la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook, >> uintptr_t *defcook, unsigned int *flags, const char *symname) >> { >> + if (*flags & LA_SYMB_NOPLTENTER) >> + warnx ("cannot trace PLT enter (bind-now enabled)"); > > OK. Awesome! :-) > >> + >> + if (do_exit && *flags & LA_SYMB_NOPLTEXIT) >> + warnx ("cannot trace PLT exit (bind-now enabled)"); > > OK. > >> + >> if (!do_exit) >> *flags = LA_SYMB_NOPLTEXIT; >> >> diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c >> new file mode 100644 >> index 0000000000..2cdd3fb98b >> --- /dev/null >> +++ b/elf/tst-audit24a.c >> @@ -0,0 +1,36 @@ >> +/* DL_AUDIT test for la_symbind and bind-now. > > s/DL_AUDIT/LD_AUDIT/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <support/check.h> >> +#include <support/support.h> >> + >> +int tst_audit24amod1_func1 (void); >> +int tst_audit24amod1_func2 (void); >> +int tst_audit24amod2_func1 (void); > > OK. Calling 3 DSO functions with args. > >> + >> +int >> +do_test (void) >> +{ >> + TEST_COMPARE (tst_audit24amod1_func1 (), 1); >> + TEST_COMPARE (tst_audit24amod1_func2 (), 2); >> + TEST_COMPARE (tst_audit24amod2_func1 (), 10); >> + >> + return 0; >> +} >> + >> +#include <support/test-driver.c> >> diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c >> new file mode 100644 >> index 0000000000..c287372e32 >> --- /dev/null >> +++ b/elf/tst-audit24amod1.c >> @@ -0,0 +1,31 @@ >> +/* Modules used by tst-audit24a. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <stdlib.h> >> + >> +_Noreturn int >> +tst_audit24amod1_func1 (void) >> +{ >> + abort (); > > OK. Calls abort. Needs redirecting. > >> +} >> + >> +int >> +tst_audit24amod1_func2 (void) >> +{ >> + return 2; > > OK. > >> +} >> diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c >> new file mode 100644 >> index 0000000000..938c71dc29 >> --- /dev/null >> +++ b/elf/tst-audit24amod2.c >> @@ -0,0 +1,25 @@ >> +/* Modules used by tst-audit24a. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <stdlib.h> >> + >> +_Noreturn int >> +tst_audit24amod2_func1 (void) >> +{ >> + abort (); > > OK. Function aborts. Needs redirecting. > >> +} >> diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c >> new file mode 100644 >> index 0000000000..82478ed8f9 >> --- /dev/null >> +++ b/elf/tst-audit24b.c >> @@ -0,0 +1,37 @@ >> +/* DL_AUDIT test for la_symbind and bind-now. > > s/DL_AUDIT/LD_AUDIT/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +/* This is similar to tst-audit24a, with the difference this modules >> + does not have the .gnu.version section header. */ >> + >> +#include <support/check.h> >> +#include <support/support.h> >> + >> +int tst_audit24bmod1_func1 (void); >> +int tst_audit24bmod1_func2 (void); >> + >> +int >> +do_test (void) >> +{ >> + TEST_COMPARE (tst_audit24bmod1_func1 (), 1); >> + TEST_COMPARE (tst_audit24bmod1_func2 (), 2); > > OK. Second test. Call two DSO functions. > >> + >> + return 0; >> +} >> + >> +#include <support/test-driver.c> >> diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c >> new file mode 100644 >> index 0000000000..5fa4611918 >> --- /dev/null >> +++ b/elf/tst-audit24bmod1.c >> @@ -0,0 +1,31 @@ >> +/* Modules used by tst-audit24c. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +int tst_audit24bmod2_func1 (void); >> + >> +int >> +tst_audit24bmod1_func1 (void) >> +{ >> + return -1; >> +} >> + >> +int >> +tst_audit24bmod1_func2 (void) >> +{ >> + return tst_audit24bmod2_func1 (); > > OK. fun2 calls func1 in dependent DSO. > >> +} >> diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c >> new file mode 100644 >> index 0000000000..d469e70a41 >> --- /dev/null >> +++ b/elf/tst-audit24bmod2.c >> @@ -0,0 +1,23 @@ >> +/* Modules used by tst-audit24b. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +int >> +tst_audit24bmod2_func1 (void) >> +{ >> + return -1; > > OK. > >> +} >> diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c >> new file mode 100644 >> index 0000000000..46ed328756 >> --- /dev/null >> +++ b/elf/tst-audit24c.c >> @@ -0,0 +1,2 @@ >> +/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now */ >> +#include "tst-audit24a.c" > > OK. > >> diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c >> new file mode 100644 >> index 0000000000..1c89e4cb83 >> --- /dev/null >> +++ b/elf/tst-audit24d.c >> @@ -0,0 +1,36 @@ >> +/* DL_AUDIT test for la_symbind and bind-now. > > s/DL_AUDIT/LD_AUDIT/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <support/check.h> >> +#include <support/support.h> >> + >> +int tst_audit24dmod1_func1 (void); >> +int tst_audit24dmod1_func2 (void); >> +int tst_audit24dmod2_func1 (void); >> + >> +int >> +do_test (void) >> +{ >> + TEST_COMPARE (tst_audit24dmod1_func1 (), 1); >> + TEST_COMPARE (tst_audit24dmod1_func2 (), 32); >> + TEST_COMPARE (tst_audit24dmod2_func1 (), 10); > > OK. Call functions in 2 DSOs. > >> + >> + return 0; >> +} >> + >> +#include <support/test-driver.c> >> diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c >> new file mode 100644 >> index 0000000000..3ff2218c96 >> --- /dev/null >> +++ b/elf/tst-audit24dmod1.c >> @@ -0,0 +1,33 @@ >> +/* Modules used by tst-audit24d. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <stdlib.h> >> + >> +int tst_audit24dmod3_func1 (void); >> + >> +_Noreturn int >> +tst_audit24dmod1_func1 (void) >> +{ >> + abort (); > > OK. Function aborts. Needs redirection. > >> +} >> + >> +int >> +tst_audit24dmod1_func2 (void) >> +{ >> + return 2 + tst_audit24dmod3_func1 ();; > > s/;;/;/g > > OK. Calls 3rd DSO. > >> +} >> diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c >> new file mode 100644 >> index 0000000000..03fe938128 >> --- /dev/null >> +++ b/elf/tst-audit24dmod2.c >> @@ -0,0 +1,28 @@ >> +/* Module for tst-audit24d. >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <stdlib.h> >> + >> +int tst_audit24dmod4_func1 (void); >> + >> +_Noreturn int >> +tst_audit24dmod2_func1 (void) >> +{ >> + tst_audit24dmod4_func1 (); >> + abort (); > > OK. Calls 4th DSO and *then* aborts. > >> +} >> diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c >> new file mode 100644 >> index 0000000000..106d517d28 >> --- /dev/null >> +++ b/elf/tst-audit24dmod3.c >> @@ -0,0 +1,31 @@ >> +/* Module for tst-audit24d. >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <stdlib.h> >> + >> +_Noreturn int >> +tst_audit24dmod3_func1 (void) >> +{ >> + abort (); >> +} >> + >> +int >> +tst_audit24dmod3_func2 (void) >> +{ >> + return 4; >> +} > > OK. > >> diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c >> new file mode 100644 >> index 0000000000..1da3b46917 >> --- /dev/null >> +++ b/elf/tst-audit24dmod4.c >> @@ -0,0 +1,25 @@ >> +/* Module for tst-audit24d. >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <stdlib.h> >> + >> +_Noreturn int >> +tst_audit24dmod4_func1 (void) >> +{ >> + abort (); >> +} > > OK. > >> diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c >> new file mode 100644 >> index 0000000000..3476069353 >> --- /dev/null >> +++ b/elf/tst-audit25a.c >> @@ -0,0 +1,129 @@ >> +/* Check DT_AUDIT and LD_BIND_NOW. > > s/DT_AUDIT/LD_AUDIT/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <array_length.h> >> +#include <errno.h> >> +#include <getopt.h> >> +#include <limits.h> >> +#include <inttypes.h> >> +#include <string.h> >> +#include <stdlib.h> >> +#include <support/capture_subprocess.h> >> +#include <support/check.h> >> +#include <support/xstdio.h> >> +#include <support/support.h> >> +#include <sys/auxv.h> >> + >> +static int restart; >> +#define CMDLINE_OPTIONS \ >> + { "restart", no_argument, &restart, 1 }, >> + >> +void tst_audit25mod1_func1 (void); >> +void tst_audit25mod1_func2 (void); >> +void tst_audit25mod2_func1 (void); >> +void tst_audit25mod2_func2 (void); >> + >> +static int >> +handle_restart (void) >> +{ >> + tst_audit25mod1_func1 (); >> + tst_audit25mod1_func2 (); >> + tst_audit25mod2_func1 (); >> + tst_audit25mod2_func2 (); >> + >> + return 0; >> +} >> + >> +static inline bool >> +startswith (const char *str, const char *pre) >> +{ >> + size_t lenpre = strlen (pre); >> + size_t lenstr = strlen (str); >> + return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0; >> +} >> + >> +static int >> +do_test (int argc, char *argv[]) >> +{ >> + /* We must have either: >> + - One our fource parameters left if called initially: > > s/One our fource/One or four/g Ack. > >> + + path to ld.so optional >> + + "--library-path" optional >> + + the library path optional >> + + the application name */ >> + >> + if (restart) >> + return handle_restart (); >> + >> + setenv ("LD_AUDIT", "tst-auditmod25.so", 0); >> + >> + char *spargv[9]; >> + int i = 0; >> + for (; i < argc - 1; i++) >> + spargv[i] = argv[i + 1]; >> + spargv[i++] = (char *) "--direct"; >> + spargv[i++] = (char *) "--restart"; >> + spargv[i] = NULL; >> + TEST_VERIFY_EXIT (i < array_length (spargv)); >> + >> + { >> + struct support_capture_subprocess result >> + = support_capture_subprogram (spargv[0], spargv); >> + support_capture_subprocess_check (&result, "tst-audit25a", 0, >> + sc_allow_stderr); > > OK. Call ourselves again. > >> + >> + /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with >> + -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to >> + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ >> + TEST_COMPARE_STRING (result.err.buffer, >> + "la_symbind: tst_audit25mod3_func1 1\n" >> + "la_symbind: tst_audit25mod1_func1 0\n" >> + "la_symbind: tst_audit25mod1_func2 0\n" >> + "la_symbind: tst_audit25mod2_func1 0\n" >> + "la_symbind: tst_audit25mod4_func1 0\n" >> + "la_symbind: tst_audit25mod2_func2 0\n"); >> + >> + support_capture_subprocess_free (&result); >> + } >> + >> + { >> + setenv ("LD_BIND_NOW", "1", 0); >> + struct support_capture_subprocess result >> + = support_capture_subprogram (spargv[0], spargv); >> + support_capture_subprocess_check (&result, "tst-audit25a", 0, >> + sc_allow_stderr); > > OK. > >> + >> + /* With LD_BIND_NOW all symbols are expected to have >> + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution >> + order is done in breadth-first order. */ >> + TEST_COMPARE_STRING (result.err.buffer, >> + "la_symbind: tst_audit25mod4_func1 1\n" >> + "la_symbind: tst_audit25mod3_func1 1\n" >> + "la_symbind: tst_audit25mod1_func1 1\n" >> + "la_symbind: tst_audit25mod2_func1 1\n" >> + "la_symbind: tst_audit25mod1_func2 1\n" >> + "la_symbind: tst_audit25mod2_func2 1\n"); >> + >> + support_capture_subprocess_free (&result); >> + } >> + >> + return 0; >> +} >> + >> +#define TEST_FUNCTION_ARGV do_test >> +#include <support/test-driver.c> >> diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c >> new file mode 100644 >> index 0000000000..8bf98bc7fd >> --- /dev/null >> +++ b/elf/tst-audit25b.c >> @@ -0,0 +1,128 @@ >> +/* Check DT_AUDIT and LD_BIND_NOW. > > s/DT_AUDIT/LD_AUDIT/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <errno.h> >> +#include <getopt.h> >> +#include <limits.h> >> +#include <inttypes.h> >> +#include <string.h> >> +#include <stdlib.h> >> +#include <support/capture_subprocess.h> >> +#include <support/check.h> >> +#include <support/xstdio.h> >> +#include <support/support.h> >> +#include <sys/auxv.h> >> + >> +static int restart; >> +#define CMDLINE_OPTIONS \ >> + { "restart", no_argument, &restart, 1 }, >> + >> +void tst_audit25mod1_func1 (void); >> +void tst_audit25mod1_func2 (void); >> +void tst_audit25mod2_func1 (void); >> +void tst_audit25mod2_func2 (void); >> + >> +static int >> +handle_restart (void) >> +{ >> + tst_audit25mod1_func1 (); >> + tst_audit25mod1_func2 (); >> + tst_audit25mod2_func1 (); >> + tst_audit25mod2_func2 (); >> + >> + return 0; >> +} >> + >> +static inline bool >> +startswith (const char *str, const char *pre) >> +{ >> + size_t lenpre = strlen (pre); >> + size_t lenstr = strlen (str); >> + return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0; >> +} >> + >> +static int >> +do_test (int argc, char *argv[]) >> +{ >> + /* We must have either: >> + - One our fource parameters left if called initially: > > s/One our fource/One or four/g Ack. > >> + + path to ld.so optional >> + + "--library-path" optional >> + + the library path optional >> + + the application name */ >> + >> + if (restart) >> + return handle_restart (); >> + >> + setenv ("LD_AUDIT", "tst-auditmod25.so", 0); >> + >> + char *spargv[9]; >> + int i = 0; >> + for (; i < argc - 1; i++) >> + spargv[i] = argv[i + 1]; >> + spargv[i++] = (char *) "--direct"; >> + spargv[i++] = (char *) "--restart"; >> + spargv[i] = NULL; >> + >> + { >> + struct support_capture_subprocess result >> + = support_capture_subprogram (spargv[0], spargv); >> + support_capture_subprocess_check (&result, "tst-audit25a", 0, >> + sc_allow_stderr); > > OK. > >> + >> + /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but >> + tst-audit25mod2 is built with -Wl,z,lazy. So only > > s/,z,/,-z,/g Ack. > >> + tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not >> + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ >> + TEST_COMPARE_STRING (result.err.buffer, >> + "la_symbind: tst_audit25mod3_func1 1\n" >> + "la_symbind: tst_audit25mod1_func1 1\n" >> + "la_symbind: tst_audit25mod2_func1 1\n" >> + "la_symbind: tst_audit25mod1_func2 1\n" >> + "la_symbind: tst_audit25mod2_func2 1\n" >> + "la_symbind: tst_audit25mod4_func1 0\n"); >> + >> + support_capture_subprocess_free (&result); >> + } >> + >> + { >> + setenv ("LD_BIND_NOW", "1", 0); >> + struct support_capture_subprocess result >> + = support_capture_subprogram (spargv[0], spargv); >> + support_capture_subprocess_check (&result, "tst-audit25a", 0, >> + sc_allow_stderr); >> + >> + /* With LD_BIND_NOW all symbols are expected to have >> + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution >> + order is done in breadth-first order. */ > > OK. > >> + TEST_COMPARE_STRING (result.err.buffer, >> + "la_symbind: tst_audit25mod4_func1 1\n" >> + "la_symbind: tst_audit25mod3_func1 1\n" >> + "la_symbind: tst_audit25mod1_func1 1\n" >> + "la_symbind: tst_audit25mod2_func1 1\n" >> + "la_symbind: tst_audit25mod1_func2 1\n" >> + "la_symbind: tst_audit25mod2_func2 1\n"); >> + >> + support_capture_subprocess_free (&result); >> + } >> + >> + return 0; >> +} >> + >> +#define TEST_FUNCTION_ARGV do_test >> +#include <support/test-driver.c> >> diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c >> new file mode 100644 >> index 0000000000..3cff8cc688 >> --- /dev/null >> +++ b/elf/tst-audit25mod1.c >> @@ -0,0 +1,30 @@ >> +/* Modules used by tst-audit25. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +void tst_audit25mod3_func1 (void); >> + >> +void >> +tst_audit25mod1_func1 (void) >> +{ >> + tst_audit25mod3_func1 (); >> +} >> + >> +void >> +tst_audit25mod1_func2 (void) >> +{ >> +} > > OK. > >> diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c >> new file mode 100644 >> index 0000000000..5e40555fa9 >> --- /dev/null >> +++ b/elf/tst-audit25mod2.c >> @@ -0,0 +1,30 @@ >> +/* Modules used by tst-audit25. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +void tst_audit25mod4_func1 (void); >> + >> +void >> +tst_audit25mod2_func1 (void) >> +{ >> + tst_audit25mod4_func1 (); >> +} >> + >> +void >> +tst_audit25mod2_func2 (void) >> +{ >> +} > > OK. > >> diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c >> new file mode 100644 >> index 0000000000..e35ed6a1da >> --- /dev/null >> +++ b/elf/tst-audit25mod3.c >> @@ -0,0 +1,22 @@ >> +/* Modules used by tst-audit25. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +void >> +tst_audit25mod3_func1 (void) >> +{ >> +} > > OK. > >> diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c >> new file mode 100644 >> index 0000000000..c3118b6368 >> --- /dev/null >> +++ b/elf/tst-audit25mod4.c >> @@ -0,0 +1,22 @@ >> +/* Modules used by tst-audit25. > > s/Modules/Module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +void >> +tst_audit25mod4_func1 (void) >> +{ >> +} > > OK. > >> diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h >> new file mode 100644 >> index 0000000000..e34c53df5e >> --- /dev/null >> +++ b/elf/tst-auditmod24.h >> @@ -0,0 +1,29 @@ >> +/* Auxiliary functions for tst-audit24x. >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#ifndef _TST_AUDITMOD24_H >> +#define _TST_AUDITMOD24_H >> + >> +static void >> +check_symbind_flags (unsigned int flags) > > Would suggest calling it "test_symbind_flags" since this is testing a specific > condition of the test and aborting if not met. Ack. > >> +{ >> + if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0) >> + abort (); > > OK. Abort if none of the flags are set. > >> +} >> + >> +#endif >> diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c >> new file mode 100644 >> index 0000000000..a4838b3e05 >> --- /dev/null >> +++ b/elf/tst-auditmod24a.c >> @@ -0,0 +1,114 @@ >> +/* Audit modules for tst-audit24a. > > s/modules/module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <link.h> >> +#include <inttypes.h> >> +#include <stdlib.h> >> +#include <string.h> >> +#include <tst-auditmod24.h> >> + >> +#define AUDIT24_COOKIE 0x1 >> +#define AUDIT24MOD1_COOKIE 0x2 >> +#define AUDIT24MOD2_COOKIE 0x3 >> + >> +#ifndef TEST_NAME >> +# define TEST_NAME "tst-audit24a" >> +#endif >> +#ifndef TEST_MOD >> +# define TEST_MOD TEST_NAME >> +#endif >> +#ifndef TEST_FUNC >> +# define TEST_FUNC "tst_audit24a" >> +#endif >> + >> +unsigned int >> +la_version (unsigned int version) >> +{ >> + return LAV_CURRENT; >> +} >> + >> +unsigned int >> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) >> +{ >> + const char *p = strrchr (map->l_name, '/'); >> + const char *l_name = p == NULL ? TEST_NAME : p + 1; >> + >> + uintptr_t ck = -1; >> + if (strcmp (l_name, TEST_MOD "mod1.so") == 0) >> + ck = AUDIT24MOD1_COOKIE; >> + else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) >> + ck = AUDIT24MOD2_COOKIE; >> + else if (strcmp (l_name, TEST_NAME) == 0) >> + ck = AUDIT24_COOKIE; >> + >> + *cookie = ck; >> + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; > > OK. > >> +} >> + >> +static int >> +tst_func1 (void) >> +{ >> + return 1; >> +} >> + >> +static int >> +tst_func2 (void) >> +{ >> + return 10; >> +} > > OK. Define two safety functions to use to avoid abort()s in the actual > implementations. > >> + >> +#if __ELF_NATIVE_CLASS == 64 >> +uintptr_t >> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#else >> +uintptr_t >> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#endif >> +{ >> + if (*refcook == AUDIT24_COOKIE) >> + { >> + if (*defcook == AUDIT24MOD1_COOKIE) >> + { >> + /* Check if bind-now symbols are advertised to not call the PLT >> + hooks. */ >> + check_symbind_flags (*flags); >> + >> + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) >> + return (uintptr_t) tst_func1; >> + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) >> + return sym->st_value; >> + abort (); >> + } >> + if (*defcook == AUDIT24MOD2_COOKIE >> + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) >> + { >> + check_symbind_flags (*flags); >> + >> + return (uintptr_t) tst_func2; >> + } >> + >> + /* malloc functions. */ >> + return sym->st_value; >> + } >> + >> + abort (); > > OK. > >> +} >> diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c >> new file mode 100644 >> index 0000000000..aefac8ced4 >> --- /dev/null >> +++ b/elf/tst-auditmod24b.c >> @@ -0,0 +1,104 @@ >> +/* Audit modules for tst-audit24b. > > s/modules/module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <link.h> >> +#include <inttypes.h> >> +#include <stdlib.h> >> +#include <string.h> >> +#include <tst-auditmod24.h> >> + >> +#define TEST_NAME "tst-audit24b" >> +#define TEST_FUNC "tst_audit24b" >> + >> +#define AUDIT24_COOKIE 0x1 >> +#define AUDIT24MOD1_COOKIE 0x2 >> +#define AUDIT24MOD2_COOKIE 0x3 >> + >> +unsigned int >> +la_version (unsigned int version) >> +{ >> + return LAV_CURRENT; >> +} >> + >> +unsigned int >> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) >> +{ >> + const char *p = strrchr (map->l_name, '/'); >> + const char *l_name = p == NULL ? TEST_NAME : p + 1; >> + >> + uintptr_t ck = -1; >> + if (strcmp (l_name, TEST_NAME "mod1.so") == 0) >> + ck = AUDIT24MOD1_COOKIE; >> + else if (strcmp (l_name, TEST_NAME "mod2.so") == 0) >> + ck = AUDIT24MOD2_COOKIE; >> + else if (strcmp (l_name, TEST_NAME) == 0) >> + ck = AUDIT24_COOKIE; >> + >> + *cookie = ck; >> + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; > > OK. > >> +} >> + >> +static int >> +tst_func1 (void) >> +{ >> + return 1; >> +} >> + >> +static int >> +tst_func2 (void) >> +{ >> + return 2; >> +} > > OK. Define two safe functions. > >> + >> +#if __ELF_NATIVE_CLASS == 64 >> +uintptr_t >> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#else >> +uintptr_t >> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#endif >> +{ >> + if (*refcook == AUDIT24_COOKIE) >> + { >> + if (*defcook == AUDIT24MOD1_COOKIE) >> + { >> + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) >> + return (uintptr_t) tst_func1; > > OK. > >> + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) >> + return sym->st_value; >> + abort (); >> + } >> + /* malloc functions. */ >> + return sym->st_value; >> + } >> + else if (*refcook == AUDIT24MOD1_COOKIE) >> + { >> + if (*defcook == AUDIT24MOD2_COOKIE >> + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) >> + { >> + check_symbind_flags (*flags); >> + return (uintptr_t) tst_func2; > > OK. > >> + } >> + } >> + >> + abort (); >> +} >> diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c >> new file mode 100644 >> index 0000000000..67e62c9d33 >> --- /dev/null >> +++ b/elf/tst-auditmod24c.c >> @@ -0,0 +1,3 @@ >> +#define TEST_NAME "tst-audit24c" >> +#define TEST_MOD "tst-audit24a" >> +#include "tst-auditmod24a.c" > > OK. > >> diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c >> new file mode 100644 >> index 0000000000..a49f00ef17 >> --- /dev/null >> +++ b/elf/tst-auditmod24d.c >> @@ -0,0 +1,120 @@ >> +/* Audit module for tst-audit24d. >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <link.h> >> +#include <inttypes.h> >> +#include <stdlib.h> >> +#include <string.h> >> +#include <tst-auditmod24.h> >> + >> +#define AUDIT24_COOKIE 0x0 >> +#define AUDIT24MOD1_COOKIE 0x1 >> +#define AUDIT24MOD2_COOKIE 0x2 >> +#define AUDIT24MOD3_COOKIE 0x3 >> +#define AUDIT24MOD4_COOKIE 0x4 >> + >> +unsigned int >> +la_version (unsigned int version) >> +{ >> + return LAV_CURRENT; > > OK. > >> +} >> + >> +unsigned int >> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) >> +{ >> + const char *p = strrchr (map->l_name, '/'); >> + const char *l_name = p == NULL ? "tst-audit24d" : p + 1; >> + >> + uintptr_t ck = -1; >> + if (strcmp (l_name, "tst-audit24dmod1.so") == 0) >> + ck = AUDIT24MOD1_COOKIE; >> + else if (strcmp (l_name, "tst-audit24dmod2.so") == 0) >> + ck = AUDIT24MOD2_COOKIE; >> + else if (strcmp (l_name, "tst-audit24dmod3.so") == 0) >> + ck = AUDIT24MOD3_COOKIE; >> + else if (strcmp (l_name, "tst-audit24dmod.so") == 0) >> + ck = AUDIT24MOD4_COOKIE; >> + else if (strcmp (l_name, "tst-audit24d") == 0) >> + ck = AUDIT24_COOKIE; >> + >> + *cookie = ck; >> + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; > > OK. > >> +} >> + >> +static int >> +tst_audit24dmod1_func1 (void) >> +{ >> + return 1; >> +} >> + >> +static int >> +tst_audit24dmod2_func1 (void) >> +{ >> + return 10; >> +} >> + >> +static int >> +tst_audit24dmod3_func1 (void) >> +{ >> + return 30; >> +} > > OK. > >> + >> +#include <stdio.h> >> + >> +#if __ELF_NATIVE_CLASS == 64 >> +uintptr_t >> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#else >> +uintptr_t >> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#endif >> +{ >> + if (*refcook == AUDIT24_COOKIE) >> + { >> + if (*defcook == AUDIT24MOD1_COOKIE) >> + { >> + if (strcmp (symname, "tst_audit24dmod1_func1") == 0) >> + return (uintptr_t) tst_audit24dmod1_func1; >> + else if (strcmp (symname, "tst_audit24dmod1_func2") == 0) >> + return sym->st_value; >> + abort (); >> + } >> + if (*defcook == AUDIT24MOD2_COOKIE >> + && (strcmp (symname, "tst_audit24dmod2_func1") == 0)) >> + return (uintptr_t) tst_audit24dmod2_func1; >> + >> + /* malloc functions. */ >> + return sym->st_value; >> + } >> + else if (*refcook == AUDIT24MOD1_COOKIE) >> + { >> + if (*defcook == AUDIT24MOD3_COOKIE >> + && strcmp (symname, "tst_audit24dmod3_func1") == 0) >> + { >> + check_symbind_flags (*flags); >> + >> + return (uintptr_t) tst_audit24dmod3_func1; >> + } >> + } >> + >> + abort (); >> +} > > OK. > >> diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c >> new file mode 100644 >> index 0000000000..526f5c54bc >> --- /dev/null >> +++ b/elf/tst-auditmod25.c >> @@ -0,0 +1,79 @@ >> +/* Audit modules for tst-audit25a. > > s/modules/module/g Ack. > >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#include <link.h> >> +#include <inttypes.h> >> +#include <stdlib.h> >> +#include <string.h> >> +#include <stdio.h> >> + >> +#define AUDIT25_COOKIE 0x1 >> +#define AUDIT25MOD1_COOKIE 0x2 >> +#define AUDIT25MOD2_COOKIE 0x3 >> +#define AUDIT25MOD3_COOKIE 0x2 >> +#define AUDIT25MOD4_COOKIE 0x3 >> + >> +#define TEST_NAME "tst-audit25" >> +#define TEST_MOD "tst-audit25" >> +#define TEST_FUNC "tst_audit25" >> + >> +unsigned int >> +la_version (unsigned int version) >> +{ >> + return LAV_CURRENT; >> +} >> + >> +unsigned int >> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) >> +{ >> + const char *p = strrchr (map->l_name, '/'); >> + const char *l_name = p == NULL ? TEST_NAME : p + 1; >> + >> + uintptr_t ck = -1; >> + if (strcmp (l_name, TEST_MOD "mod1.so") == 0) >> + ck = AUDIT25MOD1_COOKIE; >> + else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) >> + ck = AUDIT25MOD2_COOKIE; >> + else if (strcmp (l_name, TEST_MOD "mod3.so") == 0) >> + ck = AUDIT25MOD3_COOKIE; >> + else if (strcmp (l_name, TEST_MOD "mod4.so") == 0) >> + ck = AUDIT25MOD4_COOKIE; >> + else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) >> + ck = AUDIT25_COOKIE; >> + >> + *cookie = ck; >> + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; > > OK. > >> +} >> + >> +#if __ELF_NATIVE_CLASS == 64 >> +uintptr_t >> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#else >> +uintptr_t >> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, >> + uintptr_t *refcook, uintptr_t *defcook, >> + unsigned int *flags, const char *symname) >> +#endif >> +{ >> + if (*refcook != -1 && *defcook != -1) >> + fprintf (stderr, "la_symbind: %s %u\n", symname, >> + *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0); > > OK. > >> + return sym->st_value; >> +} >> diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h >> index 7460c0596a..95bcfc1cc1 100644 >> --- a/sysdeps/generic/dl-lookupcfg.h >> +++ b/sysdeps/generic/dl-lookupcfg.h >> @@ -26,3 +26,6 @@ >> #define DL_FIXUP_VALUE_CODE_ADDR(value) (value) >> #define DL_FIXUP_VALUE_ADDR(value) (value) >> #define DL_FIXUP_ADDR_VALUE(addr) (addr) >> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) >> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ >> + (*value) = st_value; > > OK. > >> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h >> index 97061bdf9f..2ebe7901c0 100644 >> --- a/sysdeps/generic/ldsodefs.h >> +++ b/sysdeps/generic/ldsodefs.h >> @@ -1431,7 +1431,10 @@ void _dl_audit_objclose (struct link_map *l) >> /* Call the la_preinit from the audit modules for the link_map L. */ >> void _dl_audit_preinit (struct link_map *l); >> >> -/* Call the la_symbind{32,64} from the audit modules for the link_map L. */ >> +/* Call the la_symbind{32,64} from the audit modules for the link_map L. If >> + RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set >> + the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling >> + la_symbind{32,64}. */ > > OK. > >> void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, >> const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, >> lookup_t result) >> diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h >> index 5d381147c0..8da2412fea 100644 >> --- a/sysdeps/hppa/dl-lookupcfg.h >> +++ b/sysdeps/hppa/dl-lookupcfg.h >> @@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map); >> #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip) >> #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) >> #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) >> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) >> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ >> + (*value) = *(struct fdesc *) (st_value) > > OK. > >> diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h >> index b8ab1bba15..3df3116b31 100644 >> --- a/sysdeps/ia64/dl-lookupcfg.h >> +++ b/sysdeps/ia64/dl-lookupcfg.h >> @@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map); >> >> #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) >> #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) >> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) >> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ >> + (*value) = *(struct fdesc *) (st_value) > > OK. > >> diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h >> new file mode 100644 >> index 0000000000..25abcc1d12 >> --- /dev/null >> +++ b/sysdeps/powerpc/dl-lookupcfg.h >> @@ -0,0 +1,39 @@ >> +/* Configuration of lookup functions. PowerPC version. >> + Copyright (C) 2022 Free Software Foundation, Inc. >> + This file is part of the GNU C Library. >> + >> + The GNU C Library is free software; you can redistribute it and/or >> + modify it under the terms of the GNU Lesser General Public >> + License as published by the Free Software Foundation; either >> + version 2.1 of the License, or (at your option) any later version. >> + >> + The GNU C Library is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + Lesser General Public License for more details. >> + >> + You should have received a copy of the GNU Lesser General Public >> + License along with the GNU C Library; if not, see >> + <https://www.gnu.org/licenses/>. */ >> + >> +#define DL_FIXUP_VALUE_TYPE ElfW(Addr) >> +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) >> +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) >> +#define DL_FIXUP_VALUE_ADDR(value) (value) >> +#define DL_FIXUP_ADDR_VALUE(addr) (addr) >> +#if __WORDSIZE == 64 && _CALL_ELF == 1 >> +/* We need to correctly set the audit modules value for bind-now. */ >> +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \ >> + (((Elf64_FuncDesc *)(addr))->fd_func) >> +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ >> + ({ \ >> + Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value); \ >> + opd->fd_func = (st_value); \ >> + if ((new_value) != (uintptr_t) (st_value)) \ >> + opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc; \ > > OK. > >> + }) >> +#else >> +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) >> +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ >> + (*value) = st_value; > > OK. > >> +#endif > >
diff --git a/NEWS b/NEWS index a9f25d3225..c0f8932f84 100644 --- a/NEWS +++ b/NEWS @@ -158,6 +158,10 @@ Deprecated and removed features, and other changes affecting compatibility: been removed. There are widely-deployed out-of-process alternatives for catching coredumps and backtraces. +* The audit module interface version LAV_CURRENT is increased to enable + proper bind-now support. The loader now advertises on the la_symbind + flags that PLT trace is not possible. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h index 7bfa4b9f4e..a852d41302 100644 --- a/bits/link_lavcurrent.h +++ b/bits/link_lavcurrent.h @@ -22,4 +22,4 @@ #endif /* Version numbers for la_version handshake interface. */ -#define LAV_CURRENT 1 +#define LAV_CURRENT 2 diff --git a/elf/Makefile b/elf/Makefile index 7d01b71f6a..b9edcccb82 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -379,6 +379,12 @@ tests += \ tst-audit21 \ tst-audit22 \ tst-audit23 \ + tst-audit24a \ + tst-audit24b \ + tst-audit24c \ + tst-audit24d \ + tst-audit25a \ + tst-audit25b \ tst-auditmany \ tst-auxobj \ tst-auxobj-dlopen \ @@ -676,6 +682,18 @@ modules-names = \ tst-audit18mod \ tst-audit19bmod \ tst-audit23mod \ + tst-audit24amod1 \ + tst-audit24amod2 \ + tst-audit24bmod1 \ + tst-audit24bmod2 \ + tst-audit24dmod1 \ + tst-audit24dmod2 \ + tst-audit24dmod3 \ + tst-audit24dmod4 \ + tst-audit25mod1 \ + tst-audit25mod2 \ + tst-audit25mod3 \ + tst-audit25mod4 \ tst-auditlogmod-1 \ tst-auditlogmod-2 \ tst-auditlogmod-3 \ @@ -701,6 +719,11 @@ modules-names = \ tst-auditmod21b \ tst-auditmod22 \ tst-auditmod23 \ + tst-auditmod24a \ + tst-auditmod24b \ + tst-auditmod24c \ + tst-auditmod24d \ + tst-auditmod25 \ tst-auxvalmod \ tst-big-note-lib \ tst-deep1mod1 \ @@ -918,7 +941,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special # rules. -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod +modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \ + tst-audit24bmod1 tst-audit24bmod2.so tests += $(tests-static) @@ -2151,6 +2175,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \ $(objpfx)tst-audit23mod.so tst-audit23-ARGS = -- $(host-test-program-cmd) +$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so +$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \ + $(objpfx)tst-audit24amod2.so +tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so +LDFLAGS-tst-audit24a = -Wl,-z,now + +$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so +$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \ + $(objpfx)tst-audit24bmod2.so +$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so +# The test check if a library without .gnu.version correctly calls the +# audit callbacks. So it uses an explicit link rule to avoid linking +# against libc.so. +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \ + -Wl,-z,now + $(call after-link,$@.new) + mv -f $@.new $@ +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1) +$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os + $(call after-link,$@.new) + mv -f $@.new $@ +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2) +tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so +LDFLAGS-tst-audit24b = -Wl,-z,now + +# Same as tst-audit24a, but tests LD_BIND_NOW +$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so +$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \ + $(objpfx)tst-audit24amod2.so +tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so +LDFLAGS-tst-audit24b = -Wl,-z,lazy + +$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so +$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \ + $(objpfx)tst-audit24dmod2.so +$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so +LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now +$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so +LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy +tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so +LDFLAGS-tst-audit24d = -Wl,-z,lazy + +$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so +$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \ + $(objpfx)tst-audit25mod2.so \ + $(objpfx)tst-audit25mod3.so \ + $(objpfx)tst-audit25mod4.so +$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so +LDFLAGS-tst-audit25mod1.so = -Wl,-z,now +$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so +LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy +tst-audit25a-ARGS = -- $(host-test-program-cmd) + +$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so +$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ + $(objpfx)tst-audit25mod2.so \ + $(objpfx)tst-audit25mod3.so \ + $(objpfx)tst-audit25mod4.so +LDFLAGS-tst-audit25b = -Wl,-z,now +tst-audit25b-ARGS = -- $(host-test-program-cmd) + # tst-sonamemove links against an older implementation of the library. LDFLAGS-tst-sonamemove-linkmod1.so = \ -Wl,--version-script=tst-sonamemove-linkmod1.map \ diff --git a/elf/dl-audit.c b/elf/dl-audit.c index 715de53272..794bfd45cd 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, lookup_t result) { - reloc_result->bound = result; - /* Compute index of the symbol entry in the symbol table of the DSO with the - definition. */ - reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result, - l_info[DT_SYMTAB])); + bool for_jmp_slot = reloc_result == NULL; + + /* Compute index of the symbol entry in the symbol table of the DSO + with the definition. */ + unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result, + l_info[DT_SYMTAB]); + if (!for_jmp_slot) + { + reloc_result->bound = result; + reloc_result->boundndx = boundndx; + } if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) { /* Set all bits since this symbol binding is not interesting. */ - reloc_result->enterexit = (1u << DL_NNS) - 1; + if (!for_jmp_slot) + reloc_result->enterexit = (1u << DL_NNS) - 1; return; } @@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, two bits. */ assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8); assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3); - reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; + uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT; const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); unsigned int flags = 0; struct audit_ifaces *afct = GLRO(dl_audit); + uintptr_t new_value = (uintptr_t) sym.st_value; for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) { /* XXX Check whether both DSOs must request action or only one */ @@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, { if (afct->symbind != NULL) { - uintptr_t new_value = afct->symbind (&sym, - reloc_result->boundndx, - &l_state->cookie, - &result_state->cookie, - &flags, - strtab2 + defsym->st_name); + flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT + : 0; + new_value = afct->symbind (&sym, boundndx, + &l_state->cookie, + &result_state->cookie, &flags, + strtab2 + defsym->st_name); if (new_value != (uintptr_t) sym.st_value) { flags |= LA_SYMB_ALTVALUE; - sym.st_value = new_value; + sym.st_value = for_jmp_slot + ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value; } } /* Remember the results for every audit library and store a summary in the first two bits. */ - reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER - | LA_SYMB_NOPLTEXIT); - reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER - | LA_SYMB_NOPLTEXIT)) - << ((cnt + 1) * 2)); + enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT); + enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) + << ((cnt + 1) * 2)); } else /* If the bind flags say this auditor is not interested, set the bits manually. */ - reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) - << ((cnt + 1) * 2)); + enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) + << ((cnt + 1) * 2)); afct = afct->next; } - reloc_result->flags = flags; - *value = DL_FIXUP_ADDR_VALUE (sym.st_value); + if (!for_jmp_slot) + { + reloc_result->enterexit = enterexit; + reloc_result->flags = flags; + } + + DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); } void diff --git a/elf/do-rel.h b/elf/do-rel.h index 0718badf83..60d5dce8f2 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -16,6 +16,8 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ +#include <ldsodefs.h> + /* This file may be included twice, to define both `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ @@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], for (; r < end; ++r) { + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; + const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; + void *const r_addr_arg = (void *) (l_addr + r->r_offset); + const struct r_found_version *rversion = &map->l_versions[ndx]; #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) { @@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], } #endif - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], - &map->l_versions[ndx], - (void *) (l_addr + r->r_offset), skip_ifunc); + elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, + skip_ifunc); +#if defined SHARED && !defined RTLD_BOOTSTRAP + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT + && GLRO(dl_naudit) > 0) + { + struct link_map *sym_map + = RESOLVE_MAP (map, scope, &sym, rversion, + ELF_MACHINE_JMP_SLOT); + if (sym != NULL) + _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map); + } +#endif } #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP @@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], else { for (; r < end; ++r) + { + const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; + void *const r_addr_arg = (void *) (l_addr + r->r_offset); # ifdef ELF_MACHINE_IRELATIVE - if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) - { - if (r2 == NULL) - r2 = r; - end2 = r; - } - else + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE) + { + if (r2 == NULL) + r2 = r; + end2 = r; + continue; + } # endif - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, - (void *) (l_addr + r->r_offset), skip_ifunc); + elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg, + skip_ifunc); +# if defined SHARED && !defined RTLD_BOOTSTRAP + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT + && GLRO(dl_naudit) > 0) + { + struct link_map *sym_map + = RESOLVE_MAP (map, scope, &sym, + (struct r_found_version *) NULL, + ELF_MACHINE_JMP_SLOT); + if (sym != NULL) + _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map); + } +# endif + } # ifdef ELF_MACHINE_IRELATIVE if (r2 != NULL) diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c index 1077458c9d..a5edd438f9 100644 --- a/elf/sotruss-lib.c +++ b/elf/sotruss-lib.c @@ -16,6 +16,7 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ +#include <err.h> #include <error.h> #include <fcntl.h> #include <stdio.h> @@ -231,6 +232,12 @@ uintptr_t la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook, uintptr_t *defcook, unsigned int *flags, const char *symname) { + if (*flags & LA_SYMB_NOPLTENTER) + warnx ("cannot trace PLT enter (bind-now enabled)"); + + if (do_exit && *flags & LA_SYMB_NOPLTEXIT) + warnx ("cannot trace PLT exit (bind-now enabled)"); + if (!do_exit) *flags = LA_SYMB_NOPLTEXIT; diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c new file mode 100644 index 0000000000..2cdd3fb98b --- /dev/null +++ b/elf/tst-audit24a.c @@ -0,0 +1,36 @@ +/* DL_AUDIT test for la_symbind and bind-now. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <support/check.h> +#include <support/support.h> + +int tst_audit24amod1_func1 (void); +int tst_audit24amod1_func2 (void); +int tst_audit24amod2_func1 (void); + +int +do_test (void) +{ + TEST_COMPARE (tst_audit24amod1_func1 (), 1); + TEST_COMPARE (tst_audit24amod1_func2 (), 2); + TEST_COMPARE (tst_audit24amod2_func1 (), 10); + + return 0; +} + +#include <support/test-driver.c> diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c new file mode 100644 index 0000000000..c287372e32 --- /dev/null +++ b/elf/tst-audit24amod1.c @@ -0,0 +1,31 @@ +/* Modules used by tst-audit24a. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +_Noreturn int +tst_audit24amod1_func1 (void) +{ + abort (); +} + +int +tst_audit24amod1_func2 (void) +{ + return 2; +} diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c new file mode 100644 index 0000000000..938c71dc29 --- /dev/null +++ b/elf/tst-audit24amod2.c @@ -0,0 +1,25 @@ +/* Modules used by tst-audit24a. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +_Noreturn int +tst_audit24amod2_func1 (void) +{ + abort (); +} diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c new file mode 100644 index 0000000000..82478ed8f9 --- /dev/null +++ b/elf/tst-audit24b.c @@ -0,0 +1,37 @@ +/* DL_AUDIT test for la_symbind and bind-now. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* This is similar to tst-audit24a, with the difference this modules + does not have the .gnu.version section header. */ + +#include <support/check.h> +#include <support/support.h> + +int tst_audit24bmod1_func1 (void); +int tst_audit24bmod1_func2 (void); + +int +do_test (void) +{ + TEST_COMPARE (tst_audit24bmod1_func1 (), 1); + TEST_COMPARE (tst_audit24bmod1_func2 (), 2); + + return 0; +} + +#include <support/test-driver.c> diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c new file mode 100644 index 0000000000..5fa4611918 --- /dev/null +++ b/elf/tst-audit24bmod1.c @@ -0,0 +1,31 @@ +/* Modules used by tst-audit24c. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +int tst_audit24bmod2_func1 (void); + +int +tst_audit24bmod1_func1 (void) +{ + return -1; +} + +int +tst_audit24bmod1_func2 (void) +{ + return tst_audit24bmod2_func1 (); +} diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c new file mode 100644 index 0000000000..d469e70a41 --- /dev/null +++ b/elf/tst-audit24bmod2.c @@ -0,0 +1,23 @@ +/* Modules used by tst-audit24b. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +int +tst_audit24bmod2_func1 (void) +{ + return -1; +} diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c new file mode 100644 index 0000000000..46ed328756 --- /dev/null +++ b/elf/tst-audit24c.c @@ -0,0 +1,2 @@ +/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now */ +#include "tst-audit24a.c" diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c new file mode 100644 index 0000000000..1c89e4cb83 --- /dev/null +++ b/elf/tst-audit24d.c @@ -0,0 +1,36 @@ +/* DL_AUDIT test for la_symbind and bind-now. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <support/check.h> +#include <support/support.h> + +int tst_audit24dmod1_func1 (void); +int tst_audit24dmod1_func2 (void); +int tst_audit24dmod2_func1 (void); + +int +do_test (void) +{ + TEST_COMPARE (tst_audit24dmod1_func1 (), 1); + TEST_COMPARE (tst_audit24dmod1_func2 (), 32); + TEST_COMPARE (tst_audit24dmod2_func1 (), 10); + + return 0; +} + +#include <support/test-driver.c> diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c new file mode 100644 index 0000000000..3ff2218c96 --- /dev/null +++ b/elf/tst-audit24dmod1.c @@ -0,0 +1,33 @@ +/* Modules used by tst-audit24d. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +int tst_audit24dmod3_func1 (void); + +_Noreturn int +tst_audit24dmod1_func1 (void) +{ + abort (); +} + +int +tst_audit24dmod1_func2 (void) +{ + return 2 + tst_audit24dmod3_func1 ();; +} diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c new file mode 100644 index 0000000000..03fe938128 --- /dev/null +++ b/elf/tst-audit24dmod2.c @@ -0,0 +1,28 @@ +/* Module for tst-audit24d. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +int tst_audit24dmod4_func1 (void); + +_Noreturn int +tst_audit24dmod2_func1 (void) +{ + tst_audit24dmod4_func1 (); + abort (); +} diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c new file mode 100644 index 0000000000..106d517d28 --- /dev/null +++ b/elf/tst-audit24dmod3.c @@ -0,0 +1,31 @@ +/* Module for tst-audit24d. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +_Noreturn int +tst_audit24dmod3_func1 (void) +{ + abort (); +} + +int +tst_audit24dmod3_func2 (void) +{ + return 4; +} diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c new file mode 100644 index 0000000000..1da3b46917 --- /dev/null +++ b/elf/tst-audit24dmod4.c @@ -0,0 +1,25 @@ +/* Module for tst-audit24d. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +_Noreturn int +tst_audit24dmod4_func1 (void) +{ + abort (); +} diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c new file mode 100644 index 0000000000..3476069353 --- /dev/null +++ b/elf/tst-audit25a.c @@ -0,0 +1,129 @@ +/* Check DT_AUDIT and LD_BIND_NOW. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <array_length.h> +#include <errno.h> +#include <getopt.h> +#include <limits.h> +#include <inttypes.h> +#include <string.h> +#include <stdlib.h> +#include <support/capture_subprocess.h> +#include <support/check.h> +#include <support/xstdio.h> +#include <support/support.h> +#include <sys/auxv.h> + +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +void tst_audit25mod1_func1 (void); +void tst_audit25mod1_func2 (void); +void tst_audit25mod2_func1 (void); +void tst_audit25mod2_func2 (void); + +static int +handle_restart (void) +{ + tst_audit25mod1_func1 (); + tst_audit25mod1_func2 (); + tst_audit25mod2_func1 (); + tst_audit25mod2_func2 (); + + return 0; +} + +static inline bool +startswith (const char *str, const char *pre) +{ + size_t lenpre = strlen (pre); + size_t lenstr = strlen (str); + return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0; +} + +static int +do_test (int argc, char *argv[]) +{ + /* We must have either: + - One our fource parameters left if called initially: + + path to ld.so optional + + "--library-path" optional + + the library path optional + + the application name */ + + if (restart) + return handle_restart (); + + setenv ("LD_AUDIT", "tst-auditmod25.so", 0); + + char *spargv[9]; + int i = 0; + for (; i < argc - 1; i++) + spargv[i] = argv[i + 1]; + spargv[i++] = (char *) "--direct"; + spargv[i++] = (char *) "--restart"; + spargv[i] = NULL; + TEST_VERIFY_EXIT (i < array_length (spargv)); + + { + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit25a", 0, + sc_allow_stderr); + + /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with + -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 0\n" + "la_symbind: tst_audit25mod1_func2 0\n" + "la_symbind: tst_audit25mod2_func1 0\n" + "la_symbind: tst_audit25mod4_func1 0\n" + "la_symbind: tst_audit25mod2_func2 0\n"); + + support_capture_subprocess_free (&result); + } + + { + setenv ("LD_BIND_NOW", "1", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit25a", 0, + sc_allow_stderr); + + /* With LD_BIND_NOW all symbols are expected to have + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution + order is done in breadth-first order. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod4_func1 1\n" + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 1\n" + "la_symbind: tst_audit25mod2_func1 1\n" + "la_symbind: tst_audit25mod1_func2 1\n" + "la_symbind: tst_audit25mod2_func2 1\n"); + + support_capture_subprocess_free (&result); + } + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include <support/test-driver.c> diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c new file mode 100644 index 0000000000..8bf98bc7fd --- /dev/null +++ b/elf/tst-audit25b.c @@ -0,0 +1,128 @@ +/* Check DT_AUDIT and LD_BIND_NOW. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <getopt.h> +#include <limits.h> +#include <inttypes.h> +#include <string.h> +#include <stdlib.h> +#include <support/capture_subprocess.h> +#include <support/check.h> +#include <support/xstdio.h> +#include <support/support.h> +#include <sys/auxv.h> + +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +void tst_audit25mod1_func1 (void); +void tst_audit25mod1_func2 (void); +void tst_audit25mod2_func1 (void); +void tst_audit25mod2_func2 (void); + +static int +handle_restart (void) +{ + tst_audit25mod1_func1 (); + tst_audit25mod1_func2 (); + tst_audit25mod2_func1 (); + tst_audit25mod2_func2 (); + + return 0; +} + +static inline bool +startswith (const char *str, const char *pre) +{ + size_t lenpre = strlen (pre); + size_t lenstr = strlen (str); + return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0; +} + +static int +do_test (int argc, char *argv[]) +{ + /* We must have either: + - One our fource parameters left if called initially: + + path to ld.so optional + + "--library-path" optional + + the library path optional + + the application name */ + + if (restart) + return handle_restart (); + + setenv ("LD_AUDIT", "tst-auditmod25.so", 0); + + char *spargv[9]; + int i = 0; + for (; i < argc - 1; i++) + spargv[i] = argv[i + 1]; + spargv[i++] = (char *) "--direct"; + spargv[i++] = (char *) "--restart"; + spargv[i] = NULL; + + { + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit25a", 0, + sc_allow_stderr); + + /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but + tst-audit25mod2 is built with -Wl,z,lazy. So only + tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 1\n" + "la_symbind: tst_audit25mod2_func1 1\n" + "la_symbind: tst_audit25mod1_func2 1\n" + "la_symbind: tst_audit25mod2_func2 1\n" + "la_symbind: tst_audit25mod4_func1 0\n"); + + support_capture_subprocess_free (&result); + } + + { + setenv ("LD_BIND_NOW", "1", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit25a", 0, + sc_allow_stderr); + + /* With LD_BIND_NOW all symbols are expected to have + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution + order is done in breadth-first order. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod4_func1 1\n" + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 1\n" + "la_symbind: tst_audit25mod2_func1 1\n" + "la_symbind: tst_audit25mod1_func2 1\n" + "la_symbind: tst_audit25mod2_func2 1\n"); + + support_capture_subprocess_free (&result); + } + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include <support/test-driver.c> diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c new file mode 100644 index 0000000000..3cff8cc688 --- /dev/null +++ b/elf/tst-audit25mod1.c @@ -0,0 +1,30 @@ +/* Modules used by tst-audit25. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +void tst_audit25mod3_func1 (void); + +void +tst_audit25mod1_func1 (void) +{ + tst_audit25mod3_func1 (); +} + +void +tst_audit25mod1_func2 (void) +{ +} diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c new file mode 100644 index 0000000000..5e40555fa9 --- /dev/null +++ b/elf/tst-audit25mod2.c @@ -0,0 +1,30 @@ +/* Modules used by tst-audit25. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +void tst_audit25mod4_func1 (void); + +void +tst_audit25mod2_func1 (void) +{ + tst_audit25mod4_func1 (); +} + +void +tst_audit25mod2_func2 (void) +{ +} diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c new file mode 100644 index 0000000000..e35ed6a1da --- /dev/null +++ b/elf/tst-audit25mod3.c @@ -0,0 +1,22 @@ +/* Modules used by tst-audit25. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +void +tst_audit25mod3_func1 (void) +{ +} diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c new file mode 100644 index 0000000000..c3118b6368 --- /dev/null +++ b/elf/tst-audit25mod4.c @@ -0,0 +1,22 @@ +/* Modules used by tst-audit25. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +void +tst_audit25mod4_func1 (void) +{ +} diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h new file mode 100644 index 0000000000..e34c53df5e --- /dev/null +++ b/elf/tst-auditmod24.h @@ -0,0 +1,29 @@ +/* Auxiliary functions for tst-audit24x. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _TST_AUDITMOD24_H +#define _TST_AUDITMOD24_H + +static void +check_symbind_flags (unsigned int flags) +{ + if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0) + abort (); +} + +#endif diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c new file mode 100644 index 0000000000..a4838b3e05 --- /dev/null +++ b/elf/tst-auditmod24a.c @@ -0,0 +1,114 @@ +/* Audit modules for tst-audit24a. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <link.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <tst-auditmod24.h> + +#define AUDIT24_COOKIE 0x1 +#define AUDIT24MOD1_COOKIE 0x2 +#define AUDIT24MOD2_COOKIE 0x3 + +#ifndef TEST_NAME +# define TEST_NAME "tst-audit24a" +#endif +#ifndef TEST_MOD +# define TEST_MOD TEST_NAME +#endif +#ifndef TEST_FUNC +# define TEST_FUNC "tst_audit24a" +#endif + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + const char *p = strrchr (map->l_name, '/'); + const char *l_name = p == NULL ? TEST_NAME : p + 1; + + uintptr_t ck = -1; + if (strcmp (l_name, TEST_MOD "mod1.so") == 0) + ck = AUDIT24MOD1_COOKIE; + else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) + ck = AUDIT24MOD2_COOKIE; + else if (strcmp (l_name, TEST_NAME) == 0) + ck = AUDIT24_COOKIE; + + *cookie = ck; + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; +} + +static int +tst_func1 (void) +{ + return 1; +} + +static int +tst_func2 (void) +{ + return 10; +} + +#if __ELF_NATIVE_CLASS == 64 +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#else +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#endif +{ + if (*refcook == AUDIT24_COOKIE) + { + if (*defcook == AUDIT24MOD1_COOKIE) + { + /* Check if bind-now symbols are advertised to not call the PLT + hooks. */ + check_symbind_flags (*flags); + + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) + return (uintptr_t) tst_func1; + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) + return sym->st_value; + abort (); + } + if (*defcook == AUDIT24MOD2_COOKIE + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) + { + check_symbind_flags (*flags); + + return (uintptr_t) tst_func2; + } + + /* malloc functions. */ + return sym->st_value; + } + + abort (); +} diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c new file mode 100644 index 0000000000..aefac8ced4 --- /dev/null +++ b/elf/tst-auditmod24b.c @@ -0,0 +1,104 @@ +/* Audit modules for tst-audit24b. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <link.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <tst-auditmod24.h> + +#define TEST_NAME "tst-audit24b" +#define TEST_FUNC "tst_audit24b" + +#define AUDIT24_COOKIE 0x1 +#define AUDIT24MOD1_COOKIE 0x2 +#define AUDIT24MOD2_COOKIE 0x3 + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + const char *p = strrchr (map->l_name, '/'); + const char *l_name = p == NULL ? TEST_NAME : p + 1; + + uintptr_t ck = -1; + if (strcmp (l_name, TEST_NAME "mod1.so") == 0) + ck = AUDIT24MOD1_COOKIE; + else if (strcmp (l_name, TEST_NAME "mod2.so") == 0) + ck = AUDIT24MOD2_COOKIE; + else if (strcmp (l_name, TEST_NAME) == 0) + ck = AUDIT24_COOKIE; + + *cookie = ck; + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; +} + +static int +tst_func1 (void) +{ + return 1; +} + +static int +tst_func2 (void) +{ + return 2; +} + +#if __ELF_NATIVE_CLASS == 64 +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#else +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#endif +{ + if (*refcook == AUDIT24_COOKIE) + { + if (*defcook == AUDIT24MOD1_COOKIE) + { + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) + return (uintptr_t) tst_func1; + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) + return sym->st_value; + abort (); + } + /* malloc functions. */ + return sym->st_value; + } + else if (*refcook == AUDIT24MOD1_COOKIE) + { + if (*defcook == AUDIT24MOD2_COOKIE + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) + { + check_symbind_flags (*flags); + return (uintptr_t) tst_func2; + } + } + + abort (); +} diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c new file mode 100644 index 0000000000..67e62c9d33 --- /dev/null +++ b/elf/tst-auditmod24c.c @@ -0,0 +1,3 @@ +#define TEST_NAME "tst-audit24c" +#define TEST_MOD "tst-audit24a" +#include "tst-auditmod24a.c" diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c new file mode 100644 index 0000000000..a49f00ef17 --- /dev/null +++ b/elf/tst-auditmod24d.c @@ -0,0 +1,120 @@ +/* Audit module for tst-audit24d. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <link.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <tst-auditmod24.h> + +#define AUDIT24_COOKIE 0x0 +#define AUDIT24MOD1_COOKIE 0x1 +#define AUDIT24MOD2_COOKIE 0x2 +#define AUDIT24MOD3_COOKIE 0x3 +#define AUDIT24MOD4_COOKIE 0x4 + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + const char *p = strrchr (map->l_name, '/'); + const char *l_name = p == NULL ? "tst-audit24d" : p + 1; + + uintptr_t ck = -1; + if (strcmp (l_name, "tst-audit24dmod1.so") == 0) + ck = AUDIT24MOD1_COOKIE; + else if (strcmp (l_name, "tst-audit24dmod2.so") == 0) + ck = AUDIT24MOD2_COOKIE; + else if (strcmp (l_name, "tst-audit24dmod3.so") == 0) + ck = AUDIT24MOD3_COOKIE; + else if (strcmp (l_name, "tst-audit24dmod.so") == 0) + ck = AUDIT24MOD4_COOKIE; + else if (strcmp (l_name, "tst-audit24d") == 0) + ck = AUDIT24_COOKIE; + + *cookie = ck; + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; +} + +static int +tst_audit24dmod1_func1 (void) +{ + return 1; +} + +static int +tst_audit24dmod2_func1 (void) +{ + return 10; +} + +static int +tst_audit24dmod3_func1 (void) +{ + return 30; +} + +#include <stdio.h> + +#if __ELF_NATIVE_CLASS == 64 +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#else +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#endif +{ + if (*refcook == AUDIT24_COOKIE) + { + if (*defcook == AUDIT24MOD1_COOKIE) + { + if (strcmp (symname, "tst_audit24dmod1_func1") == 0) + return (uintptr_t) tst_audit24dmod1_func1; + else if (strcmp (symname, "tst_audit24dmod1_func2") == 0) + return sym->st_value; + abort (); + } + if (*defcook == AUDIT24MOD2_COOKIE + && (strcmp (symname, "tst_audit24dmod2_func1") == 0)) + return (uintptr_t) tst_audit24dmod2_func1; + + /* malloc functions. */ + return sym->st_value; + } + else if (*refcook == AUDIT24MOD1_COOKIE) + { + if (*defcook == AUDIT24MOD3_COOKIE + && strcmp (symname, "tst_audit24dmod3_func1") == 0) + { + check_symbind_flags (*flags); + + return (uintptr_t) tst_audit24dmod3_func1; + } + } + + abort (); +} diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c new file mode 100644 index 0000000000..526f5c54bc --- /dev/null +++ b/elf/tst-auditmod25.c @@ -0,0 +1,79 @@ +/* Audit modules for tst-audit25a. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <link.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#define AUDIT25_COOKIE 0x1 +#define AUDIT25MOD1_COOKIE 0x2 +#define AUDIT25MOD2_COOKIE 0x3 +#define AUDIT25MOD3_COOKIE 0x2 +#define AUDIT25MOD4_COOKIE 0x3 + +#define TEST_NAME "tst-audit25" +#define TEST_MOD "tst-audit25" +#define TEST_FUNC "tst_audit25" + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + const char *p = strrchr (map->l_name, '/'); + const char *l_name = p == NULL ? TEST_NAME : p + 1; + + uintptr_t ck = -1; + if (strcmp (l_name, TEST_MOD "mod1.so") == 0) + ck = AUDIT25MOD1_COOKIE; + else if (strcmp (l_name, TEST_MOD "mod2.so") == 0) + ck = AUDIT25MOD2_COOKIE; + else if (strcmp (l_name, TEST_MOD "mod3.so") == 0) + ck = AUDIT25MOD3_COOKIE; + else if (strcmp (l_name, TEST_MOD "mod4.so") == 0) + ck = AUDIT25MOD4_COOKIE; + else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) + ck = AUDIT25_COOKIE; + + *cookie = ck; + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; +} + +#if __ELF_NATIVE_CLASS == 64 +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#else +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#endif +{ + if (*refcook != -1 && *defcook != -1) + fprintf (stderr, "la_symbind: %s %u\n", symname, + *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0); + return sym->st_value; +} diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h index 7460c0596a..95bcfc1cc1 100644 --- a/sysdeps/generic/dl-lookupcfg.h +++ b/sysdeps/generic/dl-lookupcfg.h @@ -26,3 +26,6 @@ #define DL_FIXUP_VALUE_CODE_ADDR(value) (value) #define DL_FIXUP_VALUE_ADDR(value) (value) #define DL_FIXUP_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = st_value; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 97061bdf9f..2ebe7901c0 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1431,7 +1431,10 @@ void _dl_audit_objclose (struct link_map *l) /* Call the la_preinit from the audit modules for the link_map L. */ void _dl_audit_preinit (struct link_map *l); -/* Call the la_symbind{32,64} from the audit modules for the link_map L. */ +/* Call the la_symbind{32,64} from the audit modules for the link_map L. If + RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set + the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling + la_symbind{32,64}. */ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value, lookup_t result) diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h index 5d381147c0..8da2412fea 100644 --- a/sysdeps/hppa/dl-lookupcfg.h +++ b/sysdeps/hppa/dl-lookupcfg.h @@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map); #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip) #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = *(struct fdesc *) (st_value) diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h index b8ab1bba15..3df3116b31 100644 --- a/sysdeps/ia64/dl-lookupcfg.h +++ b/sysdeps/ia64/dl-lookupcfg.h @@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map); #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = *(struct fdesc *) (st_value) diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h new file mode 100644 index 0000000000..25abcc1d12 --- /dev/null +++ b/sysdeps/powerpc/dl-lookupcfg.h @@ -0,0 +1,39 @@ +/* Configuration of lookup functions. PowerPC version. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#define DL_FIXUP_VALUE_TYPE ElfW(Addr) +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) +#define DL_FIXUP_VALUE_ADDR(value) (value) +#define DL_FIXUP_ADDR_VALUE(addr) (addr) +#if __WORDSIZE == 64 && _CALL_ELF == 1 +/* We need to correctly set the audit modules value for bind-now. */ +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \ + (((Elf64_FuncDesc *)(addr))->fd_func) +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + ({ \ + Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value); \ + opd->fd_func = (st_value); \ + if ((new_value) != (uintptr_t) (st_value)) \ + opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc; \ + }) +#else +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = st_value; +#endif