* [PATCH v9 1/4] elf: Add la_activity during application exit
2022-01-03 12:53 [PATCH v9 0/4] Multiple rtld-audit fixes Adhemerval Zanella
@ 2022-01-03 12:53 ` Adhemerval Zanella
2022-01-03 12:53 ` [PATCH v9 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Adhemerval Zanella
2022-01-03 12:53 ` [PATCH v9 3/4] elf: Issue la_symbind for bind-now (BZ #23734) Adhemerval Zanella
2 siblings, 0 replies; 7+ messages in thread
From: Adhemerval Zanella @ 2022-01-03 12:53 UTC (permalink / raw)
To: libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard
la_activity is not called during application exit, even though
la_objclose is.
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
---
elf/Makefile | 8 +-
elf/dl-fini.c | 10 ++
elf/tst-audit23.c | 240 +++++++++++++++++++++++++++++++++++++++++++
elf/tst-audit23mod.c | 23 +++++
elf/tst-auditmod23.c | 74 +++++++++++++
5 files changed, 354 insertions(+), 1 deletion(-)
create mode 100644 elf/tst-audit23.c
create mode 100644 elf/tst-audit23mod.c
create mode 100644 elf/tst-auditmod23.c
diff --git a/elf/Makefile b/elf/Makefile
index 06bfa1642f..d486be67d8 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -240,7 +240,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-audit19b \
tst-audit20 \
tst-audit22 \
- tst-rtld-run-static \
+ tst-audit23 \
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -393,6 +393,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-audit19bmod \
tst-auditmod20 \
tst-auditmod22 \
+ tst-auditmod23 \
+ tst-audit23mod \
tst-dl_find_object-mod1 \
tst-dl_find_object-mod2 \
tst-dl_find_object-mod3 \
@@ -1620,6 +1622,10 @@ tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
tst-audit22-ARGS = -- $(host-test-program-cmd)
+$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
+ $(objpfx)tst-audit23mod.so
+tst-audit23-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-fini.c b/elf/dl-fini.c
index de8eb1b3c9..2705a15c88 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -64,6 +64,11 @@ _dl_fini (void)
__rtld_lock_unlock_recursive (GL(dl_load_lock));
else
{
+#ifdef SHARED
+ /* Auditing checkpoint: we will start deleting objects. */
+ _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
+#endif
+
/* Now we can allocate an array to hold all the pointers and
copy the pointers in. */
struct link_map *maps[nloaded];
@@ -153,6 +158,11 @@ _dl_fini (void)
/* Correct the previous increment. */
--l->l_direct_opencount;
}
+
+#ifdef SHARED
+ /* Auditing checkpoint: we will start deleting objects. */
+ _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
+#endif
}
}
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
new file mode 100644
index 0000000000..29358a18a8
--- /dev/null
+++ b/elf/tst-audit23.c
@@ -0,0 +1,240 @@
+/* Check DT_AUDIT la_objopen and la_objclose for all objects.
+ Copyright (C) 2021 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 <link.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <gnu/lib-names.h>
+#include <string.h>
+#include <stdlib.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+#include <support/xdlfcn.h>
+#include <support/support.h>
+
+static int restart;
+#define CMDLINE_OPTIONS \
+ { "restart", no_argument, &restart, 1 },
+
+static int
+handle_restart (void)
+{
+ xdlopen ("tst-audit23mod.so", RTLD_NOW);
+ xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
+
+ 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 inline bool
+is_vdso (const char *str)
+{
+ return startswith (str, "linux-gate")
+ || startswith (str, "linux-vdso");
+}
+
+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 ();
+
+ 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;
+
+ setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
+ struct support_capture_subprocess result
+ = support_capture_subprogram (spargv[0], spargv);
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
+
+ /* The expected la_objopen/la_objclose:
+ 1. executable
+ 2. loader
+ 3. libc.so
+ 4. tst-audit23mod.so
+ 5. libc.so (LM_ID_NEWLM).
+ 6. vdso (optional and ignored). */
+ enum { max_objs = 6 };
+ struct la_obj_t
+ {
+ char *lname;
+ uintptr_t laddr;
+ Lmid_t lmid;
+ bool closed;
+ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
+ size_t nobjs = 0;
+
+ /* The expected namespaces are one for the audit module, one for the
+ application, and another for the dlmopen on handle_restart. */
+ enum { max_ns = 3 };
+ uintptr_t acts[max_ns];
+ size_t nacts = 0;
+ int last_act = -1;
+ uintptr_t last_act_cookie = -1;
+ bool seen_first_objclose = false;
+
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
+ TEST_VERIFY (out != NULL);
+ char *buffer = NULL;
+ size_t buffer_length = 0;
+ while (xgetline (&buffer, &buffer_length, out))
+ {
+ printf ("%s", buffer);
+ if (startswith (buffer, "la_activity: "))
+ {
+ uintptr_t cookie;
+ int this_act;
+ int r = sscanf (buffer + strlen ("la_activity: "),
+ "%d %"SCNxPTR"", &this_act, &cookie);
+ TEST_COMPARE (r, 2);
+
+ /* The cookie identifies the object at the head of the link map,
+ so we only add a new namespace if it changes from previous
+ one. This work since dlmopen is the last in the test body. */
+ if (cookie != last_act_cookie && last_act_cookie != -1)
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
+
+ if (this_act == LA_ACT_ADD && acts[nacts - 1] != cookie)
+ {
+ acts[nacts++] = cookie;
+ last_act_cookie = cookie;
+ }
+ /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
+ at program termination (if the tests adds a dlclose or a library
+ with extra dependencies this require to be adapted). */
+ else if (this_act == LA_ACT_DELETE)
+ {
+ last_act_cookie = acts[--nacts];
+ TEST_COMPARE (acts[nacts], cookie);
+ acts[nacts] = 0;
+ }
+ else if (this_act == LA_ACT_CONSISTENT)
+ {
+ TEST_COMPARE (cookie, last_act_cookie);
+
+ /* LA_ACT_DELETE must always be followed by an la_objclose. */
+ if (last_act == LA_ACT_DELETE)
+ TEST_COMPARE (seen_first_objclose, true);
+ else
+ TEST_COMPARE (last_act, LA_ACT_ADD);
+ }
+
+ last_act = this_act;
+ seen_first_objclose = false;
+ }
+ else if (startswith (buffer, "la_objopen: "))
+ {
+ char *lname;
+ uintptr_t laddr;
+ Lmid_t lmid;
+ uintptr_t cookie;
+ int r = sscanf (buffer + strlen ("la_objopen: "),
+ "%"SCNxPTR" %ms %"SCNxPTR" %ld", &cookie, &lname,
+ &laddr, &lmid);
+ TEST_COMPARE (r, 4);
+
+ /* la_objclose is not triggered by vDSO because glibc does not
+ unload it. */
+ if (is_vdso (lname))
+ continue;
+ if (nobjs == max_objs)
+ FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
+ lname, laddr, lmid);
+ objs[nobjs].lname = lname;
+ objs[nobjs].laddr = laddr;
+ objs[nobjs].lmid = lmid;
+ objs[nobjs].closed = false;
+ nobjs++;
+
+ /* This indirectly checks that la_objopen always come before
+ la_objclose btween la_activity calls. */
+ seen_first_objclose = false;
+ }
+ else if (startswith (buffer, "la_objclose: "))
+ {
+ char *lname;
+ uintptr_t laddr;
+ Lmid_t lmid;
+ uintptr_t cookie;
+ int r = sscanf (buffer + strlen ("la_objclose: "),
+ "%"SCNxPTR" %ms %"SCNxPTR" %ld", &cookie, &lname,
+ &laddr, &lmid);
+ TEST_COMPARE (r, 4);
+
+ for (size_t i = 0; i < nobjs; i++)
+ {
+ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
+ {
+ TEST_COMPARE (objs[i].closed, false);
+ objs[i].closed = true;
+ break;
+ }
+ }
+
+ /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
+ the closed object's namespace. */
+ TEST_COMPARE (last_act, LA_ACT_DELETE);
+ if (!seen_first_objclose)
+ {
+ TEST_COMPARE (last_act_cookie, cookie);
+ seen_first_objclose = true;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < nobjs; i++)
+ {
+ TEST_COMPARE (objs[i].closed, true);
+ free (objs[i].lname);
+ }
+
+ /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
+ Since only one link map may be not-CONSISTENT at a time, this also
+ ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
+ for every namespace. */
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
+
+ free (buffer);
+ xfclose (out);
+
+ return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
new file mode 100644
index 0000000000..4ca66cf772
--- /dev/null
+++ b/elf/tst-audit23mod.c
@@ -0,0 +1,23 @@
+/* Extra modules for tst-audit23
+ Copyright (C) 2021 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
+foo (void)
+{
+ return 0;
+}
diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
new file mode 100644
index 0000000000..7a6d24ee80
--- /dev/null
+++ b/elf/tst-auditmod23.c
@@ -0,0 +1,74 @@
+/* Audit modules loaded by tst-audit23.
+ Copyright (C) 2021 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 <stdio.h>
+#include <string.h>
+#include <sys/auxv.h>
+
+unsigned int
+la_version (unsigned int version)
+{
+ return LAV_CURRENT;
+}
+
+struct map_desc_t
+{
+ char *lname;
+ uintptr_t laddr;
+ Lmid_t lmid;
+};
+
+void
+la_activity (uintptr_t *cookie, unsigned int flag)
+{
+ fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+ const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
+ (uintptr_t) cookie, l_name, map->l_addr, lmid);
+
+ struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
+ if (map_desc == NULL)
+ abort ();
+
+ map_desc->lname = strdup (l_name);
+ map_desc->laddr = map->l_addr;
+ map_desc->lmid = lmid;
+
+ *cookie = (uintptr_t) map_desc;
+
+ return 0;
+}
+
+unsigned int
+la_objclose (uintptr_t *cookie)
+{
+ struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
+ (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
+ map_desc->lmid);
+
+ return 0;
+}
--
2.32.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v9 3/4] elf: Issue la_symbind for bind-now (BZ #23734)
2022-01-03 12:53 [PATCH v9 0/4] Multiple rtld-audit fixes Adhemerval Zanella
2022-01-03 12:53 ` [PATCH v9 1/4] elf: Add la_activity during application exit Adhemerval Zanella
2022-01-03 12:53 ` [PATCH v9 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Adhemerval Zanella
@ 2022-01-03 12:53 ` Adhemerval Zanella
2022-01-03 13:09 ` Andreas Schwab
2 siblings, 1 reply; 7+ messages in thread
From: Adhemerval Zanella @ 2022-01-03 12:53 UTC (permalink / raw)
To: libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard
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
program semantic (where no PTL is expected) and would incur in
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
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.
---
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 | 127 ++++++++++++++++++++++++++++++++
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, 1377 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 9da2a740ec..1e6aed1ace 100644
--- a/NEWS
+++ b/NEWS
@@ -126,6 +126,10 @@ Deprecated and removed features, and other changes affecting compatibility:
configuration script now automatically detects static-pie support in the
toolchain and architecture and enables it if available.
+* The audit module interface version LAV_CURRENT is increased to enable
+ proper bind-now support. The loader now advertise 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 4f9a9f3c8e..10c494e1e2 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -242,6 +242,12 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-audit21 \
tst-audit22 \
tst-audit23 \
+ tst-audit24a \
+ tst-audit24b \
+ tst-audit24c \
+ tst-audit24d \
+ tst-audit25a \
+ tst-audit25b \
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -398,6 +404,23 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-auditmod22 \
tst-auditmod23 \
tst-audit23mod \
+ tst-auditmod24a \
+ tst-audit24amod1 \
+ tst-audit24amod2 \
+ tst-auditmod24b \
+ tst-audit24bmod1 \
+ tst-audit24bmod2 \
+ tst-auditmod24c \
+ tst-auditmod24d \
+ tst-audit24dmod1 \
+ tst-audit24dmod2 \
+ tst-audit24dmod3 \
+ tst-audit24dmod4 \
+ tst-auditmod25 \
+ tst-audit25mod1 \
+ tst-audit25mod2 \
+ tst-audit25mod3 \
+ tst-audit25mod4 \
tst-dl_find_object-mod1 \
tst-dl_find_object-mod2 \
tst-dl_find_object-mod3 \
@@ -466,7 +489,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)
@@ -1634,6 +1658,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..134c3e7b5b
--- /dev/null
+++ b/elf/tst-audit24a.c
@@ -0,0 +1,36 @@
+/* DL_AUDIT test for la_symbind and bind-now.
+ Copyright (C) 2021 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..43d3831677
--- /dev/null
+++ b/elf/tst-audit24amod1.c
@@ -0,0 +1,31 @@
+/* Modules used by tst-audit24a.
+ Copyright (C) 2021 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..c995827855
--- /dev/null
+++ b/elf/tst-audit24amod2.c
@@ -0,0 +1,25 @@
+/* Modules used by tst-audit24a.
+ Copyright (C) 2021 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..69bf71b4c9
--- /dev/null
+++ b/elf/tst-audit24b.c
@@ -0,0 +1,37 @@
+/* DL_AUDIT test for la_symbind and bind-now.
+ Copyright (C) 2021 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..91c6fa0251
--- /dev/null
+++ b/elf/tst-audit24bmod1.c
@@ -0,0 +1,31 @@
+/* Modules used by tst-audit24c.
+ Copyright (C) 2021 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..3baf9e8bd4
--- /dev/null
+++ b/elf/tst-audit24bmod2.c
@@ -0,0 +1,23 @@
+/* Modules used by tst-audit24b.
+ Copyright (C) 2021 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..821e5a2051
--- /dev/null
+++ b/elf/tst-audit24d.c
@@ -0,0 +1,36 @@
+/* DL_AUDIT test for la_symbind and bind-now.
+ Copyright (C) 2021 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..792da3b581
--- /dev/null
+++ b/elf/tst-audit24dmod1.c
@@ -0,0 +1,33 @@
+/* Modules used by tst-audit24d.
+ Copyright (C) 2021 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..8c76257885
--- /dev/null
+++ b/elf/tst-audit24dmod2.c
@@ -0,0 +1,28 @@
+/* Module for tst-audit24d.
+ Copyright (C) 2021 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..367c776eb5
--- /dev/null
+++ b/elf/tst-audit24dmod3.c
@@ -0,0 +1,31 @@
+/* Module for tst-audit24d.
+ Copyright (C) 2021 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..c994c7cf03
--- /dev/null
+++ b/elf/tst-audit24dmod4.c
@@ -0,0 +1,25 @@
+/* Module for tst-audit24d.
+ Copyright (C) 2021 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..8d08371abd
--- /dev/null
+++ b/elf/tst-audit25a.c
@@ -0,0 +1,127 @@
+/* Check DT_AUDIT and LD_BIND_NOW.
+ Copyright (C) 2021 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 ? 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;
+
+ {
+ 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..1d748b7068
--- /dev/null
+++ b/elf/tst-audit25b.c
@@ -0,0 +1,128 @@
+/* Check DT_AUDIT and LD_BIND_NOW.
+ Copyright (C) 2021 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..9aa39ed325
--- /dev/null
+++ b/elf/tst-audit25mod1.c
@@ -0,0 +1,30 @@
+/* Modules used by tst-audit25.
+ Copyright (C) 2021 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..6d8e225fcc
--- /dev/null
+++ b/elf/tst-audit25mod2.c
@@ -0,0 +1,30 @@
+/* Modules used by tst-audit25.
+ Copyright (C) 2021 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..c0d5977fd8
--- /dev/null
+++ b/elf/tst-audit25mod3.c
@@ -0,0 +1,22 @@
+/* Modules used by tst-audit25.
+ Copyright (C) 2021 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..689ee5138f
--- /dev/null
+++ b/elf/tst-audit25mod4.c
@@ -0,0 +1,22 @@
+/* Modules used by tst-audit25.
+ Copyright (C) 2021 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..621fd50364
--- /dev/null
+++ b/elf/tst-auditmod24.h
@@ -0,0 +1,29 @@
+/* Auxiliary functions for tst-audit24x.
+ Copyright (C) 2021 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..ce8be9c22f
--- /dev/null
+++ b/elf/tst-auditmod24a.c
@@ -0,0 +1,114 @@
+/* Audit modules for tst-audit24a.
+ Copyright (C) 2021 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..d41c5adc6b
--- /dev/null
+++ b/elf/tst-auditmod24b.c
@@ -0,0 +1,104 @@
+/* Audit modules for tst-audit24b.
+ Copyright (C) 2021 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..24cae42cb8
--- /dev/null
+++ b/elf/tst-auditmod24d.c
@@ -0,0 +1,120 @@
+/* Audit module for tst-audit24d.
+ Copyright (C) 2021 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..ea4d5fe542
--- /dev/null
+++ b/elf/tst-auditmod25.c
@@ -0,0 +1,79 @@
+/* Audit modules for tst-audit25a.
+ Copyright (C) 2021 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..43fc94a7f6
--- /dev/null
+++ b/sysdeps/powerpc/dl-lookupcfg.h
@@ -0,0 +1,39 @@
+/* Configuration of lookup functions. PowerPC version.
+ Copyright (C) 2021 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
--
2.32.0
^ permalink raw reply [flat|nested] 7+ messages in thread