From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1791) id 900B8385F022; Fri, 10 Sep 2021 18:26:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 900B8385F022 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Adhemerval Zanella To: glibc-cvs@sourceware.org Subject: [glibc/azanella/ld-audit-fixes] elf: Issue audit la_objopen() for vDSO X-Act-Checkin: glibc X-Git-Author: Adhemerval Zanella X-Git-Refname: refs/heads/azanella/ld-audit-fixes X-Git-Oldrev: 71a71a2916523dd25c3c8efb157d4f2986cc01fc X-Git-Newrev: 2da037557f0a2401394fb0e0398e6480c331c041 Message-Id: <20210910182635.900B8385F022@sourceware.org> Date: Fri, 10 Sep 2021 18:26:35 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Sep 2021 18:26:35 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2da037557f0a2401394fb0e0398e6480c331c041 commit 2da037557f0a2401394fb0e0398e6480c331c041 Author: Adhemerval Zanella Date: Mon Jul 19 18:42:26 2021 -0300 elf: Issue audit la_objopen() for vDSO Diff: --- elf/Makefile | 5 +++ elf/dl-object.c | 17 +++++--- elf/rtld.c | 7 +++ elf/setup-vdso.h | 2 +- elf/tst-audit22.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ elf/tst-auditmod22.c | 37 ++++++++++++++++ include/dlfcn.h | 1 + 7 files changed, 180 insertions(+), 8 deletions(-) diff --git a/elf/Makefile b/elf/Makefile index 4006233c10..27b560c3b5 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -225,6 +225,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit19 \ tst-audit20 \ tst-audit21 \ + tst-audit22 \ tst-single_threaded tst-single_threaded-pthread \ tst-tls-ie tst-tls-ie-dlmopen argv0test \ tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \ @@ -313,6 +314,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod19 \ tst-auditmod20 tst-audit20mod \ tst-auditmod21 \ + tst-auditmod22 \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1529,6 +1531,9 @@ tst-audit20-ARGS = -- $(host-test-program-cmd) $(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21.so tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21.so +$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so +tst-audit22-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-object.c b/elf/dl-object.c index eb2158a84b..6f26da4310 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -59,16 +59,19 @@ _dl_new_object (char *realname, const char *libname, int type, { #ifdef SHARED unsigned int naudit; - if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0)) + if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0)) { - assert (type == lt_executable); - assert (nsid == LM_ID_BASE); + if (mode & __RTLD_OPENEXEC) + { + assert (type == lt_executable); + assert (nsid == LM_ID_BASE); - /* Ignore the specified libname for the main executable. It is - only known with an explicit loader invocation. */ - libname = ""; + /* Ignore the specified libname for the main executable. It is + only known with an explicit loader invocation. */ + libname = ""; + } - /* We create the map for the executable before we know whether + /* We create the map for the executable and vDSO before we know whether we have auditing libraries and if yes, how many. Assume the worst. */ naudit = DL_NNS; diff --git a/elf/rtld.c b/elf/rtld.c index 157112ccc0..d67053acd9 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1879,6 +1879,13 @@ dl_main (const ElfW(Phdr) *phdr, assert (i == npreloads); } +#ifdef NEED_DL_SYSINFO_DSO + /* Now that the audit modules are opened, call la_objopen() for the + vDSO. */ + if (GLRO(dl_sysinfo_map) != NULL) + _dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE, true); +#endif + /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD specified some libraries to load, these are inserted before the actual dependencies in the executable's searchlist for symbol resolution. */ diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h index 86c491e49c..80a447b10c 100644 --- a/elf/setup-vdso.h +++ b/elf/setup-vdso.h @@ -30,7 +30,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), We just want our data structures to describe it as if we had just mapped and relocated it normally. */ struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, - 0, LM_ID_BASE); + __RTLD_VDSO, LM_ID_BASE); if (__glibc_likely (l != NULL)) { static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c new file mode 100644 index 0000000000..c1b301c4cc --- /dev/null +++ b/elf/tst-audit22.c @@ -0,0 +1,119 @@ +/* Check DTAUDIT and vDSO interaction. + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +static uintptr_t vdso_addr; + +static int +handle_restart (void) +{ + fprintf (stderr, "vdso: %" PRIxPTR "\n", vdso_addr); + return 0; +} + +static unsigned long int +parse_address (const char *str) +{ + char *endptr; + long int ret; + errno = 0; + ret = strtol (str, &endptr, 10); + TEST_COMPARE (errno, 0); + TEST_VERIFY (ret >= 0 && ret <= INT_MAX); + return ret; +} + +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[]) +{ + vdso_addr = getauxval (AT_SYSINFO_EHDR); + if (vdso_addr == 0) + FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0"); + + /* 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-auditmod22.so", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr); + + unsigned long vdso_process = 0; + unsigned long vdso_audit = 0; + + 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)) + { + if (startswith (buffer, "vdso: ")) + vdso_process = parse_address (buffer + strlen ("vdso: ")); + else if (startswith (buffer, "vdso found: ")) + vdso_audit = parse_address (buffer + strlen ("vdso found: ")); + } + + TEST_COMPARE (vdso_process, vdso_audit); + + free (buffer); + xfclose (out); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c new file mode 100644 index 0000000000..02275bed57 --- /dev/null +++ b/elf/tst-auditmod22.c @@ -0,0 +1,37 @@ +/* Check DTAUDIT and vDSO interaction. + 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 + . */ + +#include +#include +#include +#include + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + if (map->l_addr == getauxval (AT_SYSINFO_EHDR)) + fprintf (stderr, "vdso found: %" PRIxPTR "\n", (uintptr_t) map->l_addr); + + return 0; +} diff --git a/include/dlfcn.h b/include/dlfcn.h index a4c283728f..66bcf2dff9 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -12,6 +12,7 @@ #define __RTLD_AUDIT 0x08000000 #define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */ #define __RTLD_NOIFUNC 0x02000000 /* Suppress calling ifunc functions. */ +#define __RTLD_VDSO 0x01000000 #define __LM_ID_CALLER -2