From patchwork Fri Jul 30 19:46:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44519 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 55E7E398203B for ; Fri, 30 Jul 2021 19:48:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 55E7E398203B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674518; bh=S/6Ragyf/LAPPhs9vOG630mPXkuPO1Aaa7+6vov/ABs=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Fl8DDQxvx8WJXZMR2e2w1PaYs9O25e9dpAfVpgKYN4hvPakAnATsHe8i7tpmYJtXo 6YImPeM1+wsBq5ZoTDQAqDWgjvecSOWTpNWz3VcE1BUEfnxy0wzE8Y9rrbPsHIKZQL vRKufmyRyGmoFNHUCXx+oBim58/h6dOUpS6WwrLk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id A116239730C2 for ; Fri, 30 Jul 2021 19:47:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A116239730C2 Received: by mail-pj1-x102c.google.com with SMTP id l19so16829599pjz.0 for ; Fri, 30 Jul 2021 12:47:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=S/6Ragyf/LAPPhs9vOG630mPXkuPO1Aaa7+6vov/ABs=; b=f8TQOafkXuX/nf57Ysb9qkHAkG8TlAotoLI4ikDdXe8x1QjNckEUDiyNBZr6EBXDTC vOpi3hCfluzt8IBrXRs/aURMbgETlq7qdIAFYrD+HHvdNTYdnFP5biLusXBT8m4HG6hp LhV0MnoFvrAXzFWb6cr2lDRkdhxOFtUnGDqxcu0hyfAVHecczOjMVEZUn/gg7CJOsh1h AAT+CcjtB0DkTDdZyfBaGUG7sPW6xaKuIgj5PnMgtMRacaJgB3XsDhHhNwjGBmsyY0A3 IaHGGG408OP/4ErtCQ6f40pPs+uyTn8g9Uz6wcDPyXwQzEgiPvjfVSu3AhG7YSl3CyH/ 2qBQ== X-Gm-Message-State: AOAM532UAooyfSflsgC3kKudHavhjvvJwUCBhctW8N3AATPm8TwWERm6 cpbJfOsZAjcsyTyvVtt3Y+565kABuRzeWQ== X-Google-Smtp-Source: ABdhPJxL1ZwmGBcOWoR/hcWHAgxO2fOWFLDgYW0b+9Gmt/8hSzKr+A7VXBjGTadlTxohwJMT9J+nyw== X-Received: by 2002:a17:902:d897:b029:12b:2624:8aac with SMTP id b23-20020a170902d897b029012b26248aacmr3725864plz.58.1627674446421; Fri, 30 Jul 2021 12:47:26 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:26 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 01/20] elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) Date: Fri, 30 Jul 2021 16:46:56 -0300 Message-Id: <20210730194715.881900-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The rtld-audit interfaces introduces a slowdown due to enabling profiling instrumentation (as if LD_AUDIT implied LD_PROFILE). However, instrumenting is only necessary if one of audit libraries provides PLT callbacks ( la_pltenter or la_pltexit symbols). Otherwise, the slowdown can be avoided. The following patch adjusts the logic that enables profiling to iterate over all audit modules and check if any of those provides a PLT hook. To keep la_symbind() to work even without PLT callbacks, _dl_fixup now calls the audit callback if the modules implements it. Co-authored-by: Alexander Monakov Checked on x86_64-linux-gnu and i686-linux-gnu. --- NEWS | 3 + elf/Makefile | 9 ++ elf/dl-reloc.c | 18 +++- elf/dl-runtime.c | 188 ++++++++++++++++++++++++------------------ elf/rtld.c | 8 +- elf/tst-audit18a.c | 39 +++++++++ elf/tst-audit18b.c | 94 +++++++++++++++++++++ elf/tst-audit18bmod.c | 23 ++++++ elf/tst-audit18mod.c | 17 ++++ elf/tst-auditmod18a.c | 23 ++++++ elf/tst-auditmod18b.c | 46 +++++++++++ include/link.h | 2 + 12 files changed, 383 insertions(+), 87 deletions(-) create mode 100644 elf/tst-audit18a.c create mode 100644 elf/tst-audit18b.c create mode 100644 elf/tst-audit18bmod.c create mode 100644 elf/tst-audit18mod.c create mode 100644 elf/tst-auditmod18a.c create mode 100644 elf/tst-auditmod18b.c diff --git a/NEWS b/NEWS index ea54518142..ca6e058b19 100644 --- a/NEWS +++ b/NEWS @@ -76,6 +76,9 @@ Major new features: equal to a giver integer. This function is a GNU extension, although Solaris also provides a similar function. +* The audit libraries will avoid unnecessary slowdown if PLT tracking is not + required (by not implementing the la_pltenter() or la_pltexit() callbacks). + Deprecated and removed features, and other changes affecting compatibility: * The function pthread_mutex_consistent_np has been deprecated; programs diff --git a/elf/Makefile b/elf/Makefile index d05f410592..eab664acaf 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -220,6 +220,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-dlopenfail-2 \ tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \ tst-audit14 tst-audit15 tst-audit16 tst-audit17 \ + tst-audit18a tst-audit18b \ 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 \ @@ -301,6 +302,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-unique1mod1 tst-unique1mod2 \ tst-unique2mod1 tst-unique2mod2 \ tst-auditmod9a tst-auditmod9b \ + tst-auditmod18a tst-auditmod18b tst-audit18bmod \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1486,6 +1488,13 @@ $(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os CFLAGS-.os += $(call elide-stack-protector,.os,tst-auditmod17) tst-audit17-ENV = LD_AUDIT=$(objpfx)tst-auditmod17.so +$(objpfx)tst-audit18a.out: $(objpfx)tst-auditmod18a.so +tst-audit18a-ENV = LD_AUDIT=$(objpfx)tst-auditmod18a.so + +$(objpfx)tst-audit18b.out: $(objpfx)tst-auditmod18b.so +$(objpfx)tst-audit18b: $(objpfx)tst-audit18bmod.so +tst-audit18b-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-reloc.c b/elf/dl-reloc.c index e13a672ade..c6bc1e6b4e 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -177,11 +177,25 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], const char *errstring = NULL; int lazy = reloc_mode & RTLD_LAZY; int skip_ifunc = reloc_mode & __RTLD_NOIFUNC; + bool consider_symbind = false; #ifdef SHARED /* If we are auditing, install the same handlers we need for profiling. */ if ((reloc_mode & __RTLD_AUDIT) == 0) - consider_profiling |= GLRO(dl_audit) != NULL; + { + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + /* Profiling is needed only if PLT hooks are provided. */ + if (afct->ARCH_LA_PLTENTER != NULL + || afct->ARCH_LA_PLTEXIT != NULL) + consider_profiling = 1; + if (afct->symbind != NULL) + consider_symbind = true; + + afct = afct->next; + } + } #elif defined PROF /* Never use dynamic linker profiling for gprof profiling code. */ # define consider_profiling 0 @@ -275,7 +289,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); #ifndef PROF - if (__glibc_unlikely (consider_profiling) + if (consider_profiling | consider_symbind && l->l_info[DT_PLTRELSZ] != NULL) { /* Allocate the array which will contain the already found diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 9d0d941000..29031099f5 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -43,6 +43,84 @@ # define ARCH_FIXUP_ATTRIBUTE #endif +#ifdef SHARED +static 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) +{ + 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])); + + 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; + return; + } + + /* Synthesize a symbol record where the st_value field is the result. */ + ElfW(Sym) sym = *defsym; + sym.st_value = DL_FIXUP_VALUE_ADDR (*value); + + /* Keep track whether there is any interest in tracing the call in the lower + 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; + + const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); + + unsigned int flags = 0; + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + /* XXX Check whether both DSOs must request action or only one */ + struct auditstate *l_state = link_map_audit_state (l, cnt); + struct auditstate *result_state = link_map_audit_state (result, cnt); + + if ((l_state->bindflags & LA_FLG_BINDFROM) != 0 + && (result_state->bindflags & LA_FLG_BINDTO) != 0) + { + 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); + if (new_value != (uintptr_t) sym.st_value) + { + flags |= LA_SYMB_ALTVALUE; + sym.st_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)); + } + 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)); + afct = afct->next; + } + + reloc_result->flags = flags; + *value = DL_FIXUP_ADDR_VALUE (sym.st_value); +} +#endif + /* This function is called through a special trampoline from the PLT the first time each PLT entry is called. We must perform the relocation specified in the PLT of the given shared object, and return the resolved @@ -138,6 +216,37 @@ _dl_fixup ( && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value)); +#ifdef SHARED + /* Auditing checkpoint: we have a new binding. Provide the auditing + libraries the possibility to change the value and tell us whether further + auditing is wanted. + The l_reloc_result is only allocated if there is an audit module which + provides a la_symbind(). */ + if (l->l_reloc_result != NULL) + { + /* This is the address in the array where we store the result of previous + relocations. */ + struct reloc_result *reloc_result + = &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))]; + unsigned int init = atomic_load_acquire (&reloc_result->init); + if (init == 0) + { + _dl_audit_symbind (l, reloc_result, sym, &value, result); + + /* Store the result for later runs. */ + if (__glibc_likely (! GLRO(dl_bind_not))) + { + reloc_result->addr = value; + /* Guarantee all previous writes complete before init is + updated. See CONCURRENCY NOTES below. */ + atomic_store_release (&reloc_result->init, 1); + } + } + else + value = reloc_result->addr; + } +#endif + /* Finally, fix up the plt itself. */ if (__glibc_unlikely (GLRO(dl_bind_not))) return value; @@ -296,84 +405,7 @@ _dl_profile_fixup ( auditing libraries the possibility to change the value and tell us whether further auditing is wanted. */ if (defsym != NULL && GLRO(dl_naudit) > 0) - { - 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])); - - /* Determine whether any of the two participating DSOs is - interested in auditing. */ - if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0) - { - unsigned int flags = 0; - struct audit_ifaces *afct = GLRO(dl_audit); - /* Synthesize a symbol record where the st_value field is - the result. */ - ElfW(Sym) sym = *defsym; - sym.st_value = DL_FIXUP_VALUE_ADDR (value); - - /* Keep track whether there is any interest in tracing - the call in the lower 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; - - const char *strtab2 = (const void *) D_PTR (result, - l_info[DT_STRTAB]); - - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - /* XXX Check whether both DSOs must request action or - only one */ - struct auditstate *l_state = link_map_audit_state (l, cnt); - struct auditstate *result_state - = link_map_audit_state (result, cnt); - if ((l_state->bindflags & LA_FLG_BINDFROM) != 0 - && (result_state->bindflags & LA_FLG_BINDTO) != 0) - { - 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); - if (new_value != (uintptr_t) sym.st_value) - { - flags |= LA_SYMB_ALTVALUE; - sym.st_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)); - } - 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)); - - afct = afct->next; - } - - reloc_result->flags = flags; - value = DL_FIXUP_ADDR_VALUE (sym.st_value); - } - else - /* Set all bits since this symbol binding is not interesting. */ - reloc_result->enterexit = (1u << DL_NNS) - 1; - } + _dl_audit_symbind (l, reloc_result, defsym, &value, result); #endif /* Store the result for later runs. */ diff --git a/elf/rtld.c b/elf/rtld.c index d733359eaf..374bf86a69 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1013,13 +1013,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); "la_objsearch\0" "la_objopen\0" "la_preinit\0" -#if __ELF_NATIVE_CLASS == 32 - "la_symbind32\0" -#elif __ELF_NATIVE_CLASS == 64 - "la_symbind64\0" -#else -# error "__ELF_NATIVE_CLASS must be defined" -#endif + LA_SYMBIND "\0" #define STRING(s) __STRING (s) "la_" STRING (ARCH_LA_PLTENTER) "\0" "la_" STRING (ARCH_LA_PLTEXIT) "\0" diff --git a/elf/tst-audit18a.c b/elf/tst-audit18a.c new file mode 100644 index 0000000000..36b781f9be --- /dev/null +++ b/elf/tst-audit18a.c @@ -0,0 +1,39 @@ +/* Check if DT_AUDIT a module without la_plt{enter,exit} symbols does not incur + in profiling (BZ#15533). + 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 + +/* We interpose the profile resolver and if it is called it means profiling is + enabled. */ +void +_dl_runtime_profile (ElfW(Word) addr) +{ + volatile int *p = NULL; + *p = 0; +} + +static int +do_test (void) +{ + printf ("..."); + return 0; +} + +#include diff --git a/elf/tst-audit18b.c b/elf/tst-audit18b.c new file mode 100644 index 0000000000..300197ca2e --- /dev/null +++ b/elf/tst-audit18b.c @@ -0,0 +1,94 @@ +/* Check if DT_AUDIT a module with la_plt{enter,exit} call la_symbind() + for lazy resolution. + 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 + +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +int tst_audit18bmod1_func (void); + +static int +handle_restart (void) +{ + TEST_COMPARE (tst_audit18bmod1_func (), 10); + 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 (); + + 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-auditmod18b.so", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit18b", 0, sc_allow_stderr); + + bool find_symbind = 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)) + if (startswith (buffer, "la_symbind: tst_audit18bmod1_func") == 0) + find_symbind = true; + + TEST_COMPARE (find_symbind, true); + + free (buffer); + xfclose (out); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/elf/tst-audit18bmod.c b/elf/tst-audit18bmod.c new file mode 100644 index 0000000000..9ffdcd8f3f --- /dev/null +++ b/elf/tst-audit18bmod.c @@ -0,0 +1,23 @@ +/* Extra module for tst-audit18b. + 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 + . */ + +int +tst_audit18bmod1_func (void) +{ + return 10; +} diff --git a/elf/tst-audit18mod.c b/elf/tst-audit18mod.c new file mode 100644 index 0000000000..b6eb3731ee --- /dev/null +++ b/elf/tst-audit18mod.c @@ -0,0 +1,17 @@ +/* Extra module for tst-audit18b. + 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 + . */ diff --git a/elf/tst-auditmod18a.c b/elf/tst-auditmod18a.c new file mode 100644 index 0000000000..2296382a1c --- /dev/null +++ b/elf/tst-auditmod18a.c @@ -0,0 +1,23 @@ +/* Audit module for tst-audit18a. + 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 + . */ + +unsigned int +la_version (unsigned int version) +{ + return version; +} diff --git a/elf/tst-auditmod18b.c b/elf/tst-auditmod18b.c new file mode 100644 index 0000000000..52bb88c7d7 --- /dev/null +++ b/elf/tst-auditmod18b.c @@ -0,0 +1,46 @@ +/* Audit module for tst-audit18b. + 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 + +unsigned int +la_version (unsigned int version) +{ + return version; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + return LA_FLG_BINDTO | LA_FLG_BINDFROM; +} + +uintptr_t +#if __ELF_NATIVE_CLASS == 32 +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +#else +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +#endif +{ + fprintf (stderr, "la_symbind: %s\n", symname); + return sym->st_value; +} diff --git a/include/link.h b/include/link.h index 4af16cb596..ebd0f511e2 100644 --- a/include/link.h +++ b/include/link.h @@ -355,8 +355,10 @@ struct auditstate #if __ELF_NATIVE_CLASS == 32 # define symbind symbind32 +# define LA_SYMBIND "la_symbind32" #elif __ELF_NATIVE_CLASS == 64 # define symbind symbind64 +# define LA_SYMBIND "la_symbind64" #else # error "__ELF_NATIVE_CLASS must be defined" #endif From patchwork Fri Jul 30 19:46:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44520 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 51B29397EC13 for ; Fri, 30 Jul 2021 19:49:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 51B29397EC13 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674564; bh=bOYdCZMnQcoAN2oreP8CQXV6IRexvukvT0nmjqCeUbo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=qp/qNb1/+RcMCU273BLfN7a+aZc3aSj0A1zlvma3tZu6qY1493y4DqcaWEKEXumdM 7M2vRBgxM1d3/I6BMXn38PWpVT6fkFTltn9yNBrT5FGgOGqydXsdhMuwv4jzbKYWA5 VUif23zgqYDVkauJ3Q9KPcvbCndFjj0a8bYRfEuc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by sourceware.org (Postfix) with ESMTPS id 2F144397B839 for ; Fri, 30 Jul 2021 19:47:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2F144397B839 Received: by mail-pj1-x1035.google.com with SMTP id m10-20020a17090a34cab0290176b52c60ddso15858068pjf.4 for ; Fri, 30 Jul 2021 12:47:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bOYdCZMnQcoAN2oreP8CQXV6IRexvukvT0nmjqCeUbo=; b=JClTN8+hhFFGSdHRDAlvwkkWIMKW+G7YnlhLmTkN/doTFfey1Tmqiib+U9zI3WQnsf GX6kyPe+yb+wl/Q790Z0cRvFIW3feB14E3rVWJad9hRwDSlbenA5sxCvkJ+UyfrrSvCT 0dIOqnhU5uz8PsWLuWl8g25AvW9IVNvYrL2jIgEMMEv5OsRRUhjn6SrhTB2Ipi7yxKSq hzFk99cjP7aspeYLgXUzehBTkBCV1B2FNz1AxtviRCfSwmusekzt1UmcPWxEyn7W6iOi 1HwCq0dS/OC75aITT9RZnCAvb+JaiIDCquEGskGLafQgTRNBhe4ZMydmPmg2CxZhzVnC rlxA== X-Gm-Message-State: AOAM531YPSnIDhK70OhkRzsmUJv8+Zu0wim1uo0DpSQMYmxsY26LjdBU W0mRn6BGzLfWH/GWZYbK5/id33f7qAjfOA== X-Google-Smtp-Source: ABdhPJzDH/JlhdxJYngQ2FtSRcM9/gHP1Ndoss+4tikA8kJY2OBpxw8ih0+6D4SyX8/b7ROAz5zrPw== X-Received: by 2002:a17:902:7208:b029:12c:9c9d:e0bb with SMTP id ba8-20020a1709027208b029012c9c9de0bbmr608406plb.44.1627674448036; Fri, 30 Jul 2021 12:47:28 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:27 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 02/20] elf: Add audit tests for modules with TLSDESC Date: Fri, 30 Jul 2021 16:46:57 -0300 Message-Id: <20210730194715.881900-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" --- elf/Makefile | 14 +++++++ elf/tst-audit-tlsdesc-audit.c | 23 ++++++++++++ elf/tst-audit-tlsdesc-dlopen.c | 67 ++++++++++++++++++++++++++++++++++ elf/tst-audit-tlsdesc.c | 60 ++++++++++++++++++++++++++++++ elf/tst-auditmod-tlsdesc1.c | 41 +++++++++++++++++++++ elf/tst-auditmod-tlsdesc2.c | 33 +++++++++++++++++ 6 files changed, 238 insertions(+) create mode 100644 elf/tst-audit-tlsdesc-audit.c create mode 100644 elf/tst-audit-tlsdesc-dlopen.c create mode 100644 elf/tst-audit-tlsdesc.c create mode 100644 elf/tst-auditmod-tlsdesc1.c create mode 100644 elf/tst-auditmod-tlsdesc2.c diff --git a/elf/Makefile b/elf/Makefile index eab664acaf..8dfcff088e 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -372,6 +372,20 @@ modules-names += tst-gnu2-tls1mod $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so tst-gnu2-tls1mod.so-no-z-defs = yes CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 + +tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen +modules-names += tst-auditmod-tlsdesc1 tst-auditmod-tlsdesc2 tst-audit-tlsdesc-audit +$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-auditmod-tlsdesc1.so \ + $(objpfx)tst-auditmod-tlsdesc2.so \ + $(shared-thread-library) +CFLAGS-tst-auditmod-tlsdesc1.c += -mtls-dialect=gnu2 +CFLAGS-tst-auditmod-tlsdesc2.c += -mtls-dialect=gnu2 +$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) +$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc1.so \ + $(objpfx)tst-auditmod-tlsdesc2.so +$(objpfx)tst-auditmod-tlsdesc1.so: $(objpfx)tst-auditmod-tlsdesc2.so +tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-audit-tlsdesc-audit.so +tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-audit-tlsdesc-audit.so endif ifeq (yes,$(have-protected-data)) modules-names += tst-protected1moda tst-protected1modb diff --git a/elf/tst-audit-tlsdesc-audit.c b/elf/tst-audit-tlsdesc-audit.c new file mode 100644 index 0000000000..53993830c9 --- /dev/null +++ b/elf/tst-audit-tlsdesc-audit.c @@ -0,0 +1,23 @@ +/* DT_AUDIT with modules with TLSDESC. + 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 + . */ + +unsigned int +la_version (unsigned int version) +{ + return version; +} diff --git a/elf/tst-audit-tlsdesc-dlopen.c b/elf/tst-audit-tlsdesc-dlopen.c new file mode 100644 index 0000000000..e4d631fc94 --- /dev/null +++ b/elf/tst-audit-tlsdesc-dlopen.c @@ -0,0 +1,67 @@ +/* DT_AUDIT with modules with TLSDESC. + 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 + +static void * +thr_func (void *mod) +{ + int* (*get_global1)(void) = xdlsym (mod, "get_global1"); + int* (*get_global2)(void) = xdlsym (mod, "get_global2"); + void (*set_global2)(int) = xdlsym (mod, "set_global2"); + int* (*get_local1)(void) = xdlsym (mod, "get_local1"); + int* (*get_local2)(void) = xdlsym (mod, "get_local2"); + + int *global1 = get_global1 (); + TEST_COMPARE (*global1, 0); + ++*global1; + + int *global2 = get_global2 (); + TEST_COMPARE (*global2, 0); + ++*global2; + TEST_COMPARE (*global2, 1); + + set_global2 (10); + TEST_COMPARE (*global2, 10); + + int *local1 = get_local1 (); + TEST_COMPARE (*local1, 0); + ++*local1; + + int *local2 = get_local2 (); + TEST_COMPARE (*local2, 0); + ++*local2; + + return 0; +} + +static int +do_test (void) +{ + void *mod = xdlopen ("tst-auditmod-tlsdesc1.so", RTLD_LAZY); + + pthread_t thr = xpthread_create (NULL, thr_func, mod); + void *r = xpthread_join (thr); + TEST_VERIFY (r == NULL); + + return 0; +} + +#include diff --git a/elf/tst-audit-tlsdesc.c b/elf/tst-audit-tlsdesc.c new file mode 100644 index 0000000000..3c8be81c95 --- /dev/null +++ b/elf/tst-audit-tlsdesc.c @@ -0,0 +1,60 @@ +/* DT_AUDIT with modules with TLSDESC. + 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 + +extern __thread int global1; +extern __thread int global2; +void *get_local1 (void); +void set_global2 (int v); +void *get_local2 (void); + +static void * +thr_func (void *clousure) +{ + TEST_COMPARE (global1, 0); + ++global1; + TEST_COMPARE (global2, 0); + ++global2; + TEST_COMPARE (global2, 1); + + set_global2 (10); + TEST_COMPARE (global2, 10); + + int *local1 = get_local1 (); + TEST_COMPARE (*local1, 0); + ++*local1; + + int *local2 = get_local2 (); + TEST_COMPARE (*local2, 0); + ++*local2; + + return 0; +} + +static int +do_test (void) +{ + pthread_t thr = xpthread_create (NULL, thr_func, NULL); + void *r = xpthread_join (thr); + TEST_VERIFY (r == NULL); + return 0; +} + +#include diff --git a/elf/tst-auditmod-tlsdesc1.c b/elf/tst-auditmod-tlsdesc1.c new file mode 100644 index 0000000000..61c7dd99a2 --- /dev/null +++ b/elf/tst-auditmod-tlsdesc1.c @@ -0,0 +1,41 @@ +/* DT_AUDIT with modules with TLSDESC. + 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 + . */ + +__thread int global1; + +int * +get_global1 (void) +{ + return &global1; +} + +static __thread int local1; + +void * +get_local1 (void) +{ + return &local1; +} + +extern __thread int global2; + +void +set_global2 (int v) +{ + global2 = v; +} diff --git a/elf/tst-auditmod-tlsdesc2.c b/elf/tst-auditmod-tlsdesc2.c new file mode 100644 index 0000000000..28aef635f6 --- /dev/null +++ b/elf/tst-auditmod-tlsdesc2.c @@ -0,0 +1,33 @@ +/* DT_AUDIT with modules with TLSDESC. + 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 + . */ + +__thread int global2; + +int * +get_global2 (void) +{ + return &global2; +} + +static __thread int local2; + +void * +get_local2 (void) +{ + return &local2; +} From patchwork Fri Jul 30 19:46:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44521 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0F2D63982032 for ; Fri, 30 Jul 2021 19:50:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0F2D63982032 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674616; bh=UPozPJ/C5YhT4bmqM+AfohRCytKvb7sgVv0kYY+aipA=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=LNRxYtsXjSNCODxK+mAuh4efVs3eTkVOiaV/a1slA/1Kc/OcBumgo012W9xl4UQvI Hf4v0XB6z+7wkv59mrijbQ6gHwlYARLAmck3z8sl7tkAB0VrBeqHUH87aGVbaixA87 HUA4NMvHmF/upL3ZGy1LyMDKPER+rDOVOjy2kqGQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by sourceware.org (Postfix) with ESMTPS id BB037397EC1F for ; Fri, 30 Jul 2021 19:47:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BB037397EC1F Received: by mail-pj1-x1036.google.com with SMTP id e2-20020a17090a4a02b029016f3020d867so15908924pjh.3 for ; Fri, 30 Jul 2021 12:47:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UPozPJ/C5YhT4bmqM+AfohRCytKvb7sgVv0kYY+aipA=; b=bUyQx1DK7pVlApsoRFfVg0vwriU2g5wmEUcGSl+TqmoG6oOy1RKzQJODXdLqIQoOSr XOSqiIKFryQjOHlcCgqdQd+kYfkbZWRedOEtci9lvwtqju9JSW6RC75HDG20gFKfiBAD idccP1lvG8csZ2ZX82ZIRpXnHr1onQA/pBvhHxYbpiLRyMGmMb5/74av9KeXrAz184+f Z1TJ9/VogdW9Lnu9KGXRkp/zPKdJuMhnOkwbW15WfGgdc4kHDTBveV/Vx7GaU0cNOfm5 +98M+jaJ+uJj/kacBiFJrwRsHDFj335KVj17HF7EK2okJtyp4cm2vAdxIxlKb38IzOcS +fWA== X-Gm-Message-State: AOAM532kA50dq8Ir33/ArAGpofg9Hd7iiUcPPEkJadrzRvKpz+3agSud h1KnU1xdPbsZ2Tp9Jpd2BEFNiyfDB8Zewg== X-Google-Smtp-Source: ABdhPJyKynavUFu/Q0MOtq8/pQY+kaL8mVdF74NLkn25+7uMG83unKQ+1bIjb4sO/6cSB962dVrAKw== X-Received: by 2002:a05:6a00:16d2:b029:300:200b:6572 with SMTP id l18-20020a056a0016d2b0290300200b6572mr4490675pfc.62.1627674449666; Fri, 30 Jul 2021 12:47:29 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:29 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 03/20] elf: Do not fail for failed dlopem on audit modules (BZ #28061) Date: Fri, 30 Jul 2021 16:46:58 -0300 Message-Id: <20210730194715.881900-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The dl_main() sets the LM_ID_BASE to RT_ADD just before starting to load new shared objects. The state is set to R_CONSISTENT just after all objects are loaded. However if a audit modules tries to dlmopen() an inexistent module, the _dl_open() will assert that the namespace is in an inconsistent state. This is different than dlopen(), since it will not use LM_ID_BASE and _dl_map_object_from_fd() is the sole responsible to set and reset the r_state value. So the assert() on _dl_open() can not really see if the state is consistent since it is _dt_main() that reset is. This patch removes the assert. Checked on x86_64-linux-gnu. --- elf/Makefile | 5 ++++ elf/dl-open.c | 2 -- elf/tst-audit19.c | 25 +++++++++++++++++++ elf/tst-auditmod19.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 elf/tst-audit19.c create mode 100644 elf/tst-auditmod19.c diff --git a/elf/Makefile b/elf/Makefile index 8dfcff088e..e44a4a1400 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -221,6 +221,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \ tst-audit14 tst-audit15 tst-audit16 tst-audit17 \ tst-audit18a tst-audit18b \ + tst-audit19 \ 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 \ @@ -303,6 +304,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-unique2mod1 tst-unique2mod2 \ tst-auditmod9a tst-auditmod9b \ tst-auditmod18a tst-auditmod18b tst-audit18bmod \ + tst-auditmod19 \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1509,6 +1511,9 @@ $(objpfx)tst-audit18b.out: $(objpfx)tst-auditmod18b.so $(objpfx)tst-audit18b: $(objpfx)tst-audit18bmod.so tst-audit18b-ARGS = -- $(host-test-program-cmd) +$(objpfx)tst-audit19.out: $(objpfx)tst-auditmod19.so +tst-audit19-ENV = LD_AUDIT=$(objpfx)tst-auditmod19.so + # 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-open.c b/elf/dl-open.c index ec386626f9..f25340968f 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -899,8 +899,6 @@ no more namespaces available for dlmopen()")); the flag here. */ } - assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); - /* Release the lock. */ __rtld_lock_unlock_recursive (GL(dl_load_lock)); diff --git a/elf/tst-audit19.c b/elf/tst-audit19.c new file mode 100644 index 0000000000..6f39ccee86 --- /dev/null +++ b/elf/tst-audit19.c @@ -0,0 +1,25 @@ +/* Check dlopen failure on audit modules. + 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 + . */ + +static int +do_test (void) +{ + return 0; +} + +#include diff --git a/elf/tst-auditmod19.c b/elf/tst-auditmod19.c new file mode 100644 index 0000000000..c57e50ee4e --- /dev/null +++ b/elf/tst-auditmod19.c @@ -0,0 +1,57 @@ +/* Check dlopen failure on audit modules. + 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 + +unsigned int +la_version (unsigned int v) +{ + return LAV_CURRENT; +} + +static void +check (void) +{ + { + void *mod = dlopen ("nonexistent.so", RTLD_NOW); + if (mod != NULL) + abort (); + } + + { + void *mod = dlmopen (LM_ID_BASE, "nonexistent.so", RTLD_NOW); + if (mod != NULL) + abort (); + } +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag != LA_ACT_CONSISTENT) + return; + check (); +} + +void +la_preinit (uintptr_t *cookie) +{ + check (); +} From patchwork Fri Jul 30 19:46:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44522 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 81C07398242C for ; Fri, 30 Jul 2021 19:51:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 81C07398242C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674661; bh=G+C/yTrSBYpakBBhVXSKjXpbvqvu5KppBHS+Y98Inrg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=hNUPRw1qMPQ2PwWB0ar0EtNuzilyGp5lH/YAgwIkeKRaiWrvWwX+kai6h3A/Y9aes CNGd4C3BDXmwsbxXXbb8FHvzhJFA8eGYtpjOYiu7Aw/WpRjMKDdPnB7lDlNjK6Csnu gggTF9jJcGGi/+GNn1WU+SyFkB/VEbOL08wcjNAM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by sourceware.org (Postfix) with ESMTPS id 9F65E3982019 for ; Fri, 30 Jul 2021 19:47:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9F65E3982019 Received: by mail-pj1-x102f.google.com with SMTP id pj14-20020a17090b4f4eb029017786cf98f9so5272781pjb.2 for ; Fri, 30 Jul 2021 12:47:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=G+C/yTrSBYpakBBhVXSKjXpbvqvu5KppBHS+Y98Inrg=; b=TyWTku3jG3v8rj0GViRy+bhEDlGYerZ4QN9XMOStWzzdP8hAlXSUQ1Lird+R4P0jTm 0Uj9x3o/vaV41wXZKjX7EWB8Z5jjnnlbNbNDYGxsCWwnFILgLAdwSo/K2qa4sbXpmt6k 8IOAWxKYu1lFqDCY0/Hn0f5VnM5Zj6KI4nCmArvgGEEaBBQdvAdkNw1BgymB6CIWVWHB FDO9D2XRKtbSueHCLVJlMDJA+i+UhpJxA8x+spk5rWUKCeAafDhrDS/oe99zPMOGQI9l qR31eAA6RFaF1B5c2HTVEoi+YdLRZalIXP4+x8g8tKujoTaKrq5Yqpy5g4+7M8DrnoWG OuEw== X-Gm-Message-State: AOAM531XfsOQ9ceXEFp+7JeT4c9vlA88NII27lVukr3eeosF/UvnN4jK ZyZOYneQO0Qr9gJZJ+miRKHU9bDo8GNQOg== X-Google-Smtp-Source: ABdhPJxOMZxDHwCMX9FCPTRYrPYu6CEyE9UPl9CF4Lm9zoPN+WZlEhOYoFvMUWNrKFrcbIjwqeLYig== X-Received: by 2002:a63:1d41:: with SMTP id d1mr3682180pgm.199.1627674453480; Fri, 30 Jul 2021 12:47:33 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:33 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 04/20] elf: Suppress audit calls when a (new) namespace is empty (BZ #28062) Date: Fri, 30 Jul 2021 16:46:59 -0300 Message-Id: <20210730194715.881900-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" From: Vivek Das Mohapatra For a new Lmid_t the namespace link_map list is empty, so it requires to check its value if before using it. This can happen for when audit module is used along with dlmopen. Checked on x86_64-linux-gnu. Co-authored-by: Adhemerval Zanella --- elf/Makefile | 6 ++ elf/dl-load.c | 7 ++- elf/tst-audit20.c | 129 +++++++++++++++++++++++++++++++++++++++++++ elf/tst-audit20mod.c | 26 +++++++++ elf/tst-auditmod20.c | 73 ++++++++++++++++++++++++ 5 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 elf/tst-audit20.c create mode 100644 elf/tst-audit20mod.c create mode 100644 elf/tst-auditmod20.c diff --git a/elf/Makefile b/elf/Makefile index e44a4a1400..519ba595dc 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -222,6 +222,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit14 tst-audit15 tst-audit16 tst-audit17 \ tst-audit18a tst-audit18b \ tst-audit19 \ + tst-audit20 \ 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 \ @@ -305,6 +306,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod9a tst-auditmod9b \ tst-auditmod18a tst-auditmod18b tst-audit18bmod \ tst-auditmod19 \ + tst-auditmod20 tst-audit20mod \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1514,6 +1516,10 @@ tst-audit18b-ARGS = -- $(host-test-program-cmd) $(objpfx)tst-audit19.out: $(objpfx)tst-auditmod19.so tst-audit19-ENV = LD_AUDIT=$(objpfx)tst-auditmod19.so +$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so \ + $(objpfx)tst-audit20mod.so +tst-audit20-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-load.c b/elf/dl-load.c index 650e4edc35..433a59191a 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1062,8 +1062,11 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, && __glibc_unlikely (GLRO(dl_naudit) > 0)) { struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; - /* Do not call the functions for any auditing object. */ - if (head->l_auditing == 0) + /* Do not call the functions for any auditing object and also do not + try to call auditing functions if the namespace is currently + empty. This happens when opening the first DSO in a new + namespace. */ + if (head != NULL && head->l_auditing == 0) { struct audit_ifaces *afct = GLRO(dl_audit); for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) diff --git a/elf/tst-audit20.c b/elf/tst-audit20.c new file mode 100644 index 0000000000..215ae17fdd --- /dev/null +++ b/elf/tst-audit20.c @@ -0,0 +1,129 @@ +/* Check DT_AUDIT with dlmopen. + 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 int +handle_restart (void) +{ + { + void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); + + pid_t (*s)(void) = xdlsym (h, "getpid"); + TEST_COMPARE (s (), getpid ()); + + xdlclose (h); + } + + { + void *h = xdlmopen (LM_ID_NEWLM, "tst-audit20mod.so", RTLD_NOW); + + int (*foo)(void) = xdlsym (h, "foo"); + TEST_COMPARE (foo (), 10); + + xdlclose (h); + } + + return 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 (); + + 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-auditmod20.so", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit20", 0, sc_allow_stderr); + + struct + { + const char *name; + bool found; + } audit_iface[] = + { + { "la_version", false }, + { "la_objsearch", false }, + { "la_activity", false }, + { "la_objopen", false }, + { "la_objclose", false }, + { "la_preinit", false }, +#if __WORDSIZE == 32 + { "la_symbind32", false }, +#elif __WORDSIZE == 64 + { "la_symbind64", false }, +#endif + }; + + /* Some hooks are called more than once but the test only check if any + is called at least once. */ + 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)) + { + for (int i = 0; i < array_length (audit_iface); i++) + if (strncmp (buffer, audit_iface[i].name, + strlen (audit_iface[i].name)) == 0) + audit_iface[i].found = true; + } + free (buffer); + xfclose (out); + + for (int i = 0; i < array_length (audit_iface); i++) + TEST_COMPARE (audit_iface[i].found, true); + + support_capture_subprocess_free (&result); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/elf/tst-audit20mod.c b/elf/tst-audit20mod.c new file mode 100644 index 0000000000..f229c4139b --- /dev/null +++ b/elf/tst-audit20mod.c @@ -0,0 +1,26 @@ +/* Check DT_AUDIT with dlmopen. + 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 + +int +foo (void) +{ + return 10; +} diff --git a/elf/tst-auditmod20.c b/elf/tst-auditmod20.c new file mode 100644 index 0000000000..182992e9fd --- /dev/null +++ b/elf/tst-auditmod20.c @@ -0,0 +1,73 @@ +/* Check DT_AUDIT with dlmopen. + 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 + +unsigned int +la_version (unsigned int version) +{ + fprintf (stderr, "%s\n", __func__); + return LAV_CURRENT; +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + fprintf (stderr, "%s\n", __func__); + return (char *) name; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + fprintf (stderr, "%s\n", __func__); +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + fprintf (stderr, "%s\n", __func__); + return LA_FLG_BINDTO | LA_FLG_BINDFROM; +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + fprintf (stderr, "%s\n", __func__); + return 0; +} + +void +la_preinit (uintptr_t *cookie) +{ + fprintf (stderr, "%s\n", __func__); +} + +uintptr_t +#if __ELF_NATIVE_CLASS == 32 +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +#else +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +#endif +{ + fprintf (stderr, "%s\n", __func__); + return sym->st_value; +} From patchwork Fri Jul 30 19:47:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44523 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7EB34384F00D for ; Fri, 30 Jul 2021 19:51:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7EB34384F00D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674708; bh=znrKQgboyfDIg6UhYGDE4sLpUjA0XsGPbvkRUZyc69A=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Wk5QR0lXtTWU/VWYMUwodv8i1iWGCqlPT5FNJsVEdInp9ai8wJ3UnSIExYNsNcOb7 8OzcggFNNx5wKB8TZSHZdv//lvmPotglk7Jps9bY/YKzLcqqDDlmeM58N4na3ZVN9o 2NBXv2gjcG6h4Ze0ulUkatp0ib067CrGQBkf95oc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id 476983982420 for ; Fri, 30 Jul 2021 19:47:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 476983982420 Received: by mail-pl1-x62e.google.com with SMTP id k1so12304307plt.12 for ; Fri, 30 Jul 2021 12:47:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=znrKQgboyfDIg6UhYGDE4sLpUjA0XsGPbvkRUZyc69A=; b=n7UtK4ARFnhJ9vbT6Hx1IZHsuybeb9oQG+0Bz6AwG48vOb/SVd41c1FI1wv3A4Iq1m tMBMXcsFnp4lW8WTDs8u1twFIxyEqSyXCreWBaIGaiwiL2e09w1IxSql8hWD1by009mL WFOwkWLjCoMciN37r42OVRwiXvLRdbll470n6NE9LDykzGNTacNkMBnIur9tEyVjVRKo n5aFS/PLlJppJS7s2zZP+TOJjFvr/votJZJ2hgiwjpg683EgyIYcpy3uTC28vFP99muo gAIffo/OEcz2cwPi+4QWQlO8jHqF0sGNZf1C20h46u331sJj4j5rivgpE0DC+97dh8Vk yARg== X-Gm-Message-State: AOAM530PrWcJJBHtdpYAb6wEY9seFqCNGAHnbTFKxkXif0FcMIF1Dyo7 Rxj6d5lasE97FlVAk4KQlujN+ufcQOHQ4Q== X-Google-Smtp-Source: ABdhPJxKn6uyQPZy386+pLfJkAJj9z23+p/4Clb62CmtYrYI7wamrOdImm1Thwn+2MUgW1bdLioTgA== X-Received: by 2002:a17:902:c711:b029:12c:9b3c:9986 with SMTP id p17-20020a170902c711b029012c9b3c9986mr1468558plp.44.1627674455192; Fri, 30 Jul 2021 12:47:35 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:34 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 05/20] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Date: Fri, 30 Jul 2021 16:47:00 -0300 Message-Id: <20210730194715.881900-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" For ldaudit modules or dependencies with initial-exec TLS, we can not set the initial TLS image on default loader initialization because it would already be set by the ldaudit setup. However, subsequent thread creation would need to follow the default behaviour. This patch fixes by making_dl_new_object() sets a new link_map flag 'l_dont_set_tls_static' only for __RTLD_AUDIT modules. The flag is later reset on _dl_allocate_tls_init(). Checked on x86_64-linux-gnu. --- elf/Makefile | 5 ++++ elf/dl-object.c | 3 ++ elf/dl-tls.c | 16 +++++++--- elf/rtld.c | 2 ++ elf/tst-audit21.c | 42 +++++++++++++++++++++++++++ elf/tst-auditmod21.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ include/link.h | 2 ++ 7 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 elf/tst-audit21.c create mode 100644 elf/tst-auditmod21.c diff --git a/elf/Makefile b/elf/Makefile index 519ba595dc..78ab9f2228 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -223,6 +223,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit18a tst-audit18b \ tst-audit19 \ tst-audit20 \ + tst-audit21 \ 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 \ @@ -307,6 +308,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod18a tst-auditmod18b tst-audit18bmod \ tst-auditmod19 \ tst-auditmod20 tst-audit20mod \ + tst-auditmod21 \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1520,6 +1522,9 @@ $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so \ $(objpfx)tst-audit20mod.so tst-audit20-ARGS = -- $(host-test-program-cmd) +$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21.so +tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21.so + # 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 1875599eb2..eb2158a84b 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -175,6 +175,9 @@ _dl_new_object (char *realname, const char *libname, int type, new->l_local_scope[0] = &new->l_searchlist; + if (mode & __RTLD_AUDIT) + new->l_dont_set_tls_static = 1; + /* Determine the origin. If allocating the link map for the main executable, the realname is not known and "". In this case, the origin needs to be determined by other means. However, in case diff --git a/elf/dl-tls.c b/elf/dl-tls.c index 423e380f7c..4763fdb856 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -593,10 +593,18 @@ _dl_allocate_tls_init (void *result) some platforms use in static programs requires it. */ dtv[map->l_tls_modid].pointer.val = dest; - /* Copy the initialization image and clear the BSS part. */ - memset (__mempcpy (dest, map->l_tls_initimage, - map->l_tls_initimage_size), '\0', - map->l_tls_blocksize - map->l_tls_initimage_size); + /* Copy the initialization image and clear the BSS part. For + ldaudit modules or depedencies with initial-exec TLS, we can not + set the initial TLS image on default loader initialization + because it would already be set by the ldaudit setup. However, + subsequent thread creation would need to follow the default + behaviour. */ + if (__glibc_unlikely (!map->l_dont_set_tls_static)) + memset (__mempcpy (dest, map->l_tls_initimage, + map->l_tls_initimage_size), '\0', + map->l_tls_blocksize - map->l_tls_initimage_size); + else + map->l_dont_set_tls_static = 0; } total += cnt; diff --git a/elf/rtld.c b/elf/rtld.c index 374bf86a69..1312378b5f 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1053,6 +1053,8 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); /* Mark the DSO as being used for auditing. */ dlmargs.map->l_auditing = 1; + /* Mark the DSO to not clear the TLS bss in tls initialization. */ + dlmargs.map->l_dont_set_tls_static = 1; } /* Notify the the audit modules that the object MAP has already been diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c new file mode 100644 index 0000000000..7f4996d66f --- /dev/null +++ b/elf/tst-audit21.c @@ -0,0 +1,42 @@ +/* Check DT_AUDIT with static TLS. + 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 + +static volatile __thread int out __attribute__ ((tls_model ("initial-exec"))); + +static void * +tf (void *) +{ + TEST_COMPARE (out, 0); + out = isspace (' '); + return NULL; +} + +int main (int argc, char *argv[]) +{ + TEST_COMPARE (out, 0); + out = isspace (' '); + + pthread_t t = xpthread_create (NULL, tf, NULL); + xpthread_join (t); + + return 0; +} diff --git a/elf/tst-auditmod21.c b/elf/tst-auditmod21.c new file mode 100644 index 0000000000..e6248622f4 --- /dev/null +++ b/elf/tst-auditmod21.c @@ -0,0 +1,69 @@ +/* Check DT_AUDIT with static TLS. + 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 + +#define tls_ie __attribute__ ((tls_model ("initial-exec"))) + +__thread int tls_var0 tls_ie; +__thread int tls_var1 tls_ie = 0x10; + +static volatile int out; + +static void +call_libc (void) +{ + /* isspace() access the initial-exec glibc TLS variables, which are + setup in glibc initialization. */ + out = isspace (' '); +} + +unsigned int +la_version (unsigned int v) +{ + tls_var0 = 0x1; + if (tls_var1 != 0x10) + abort (); + tls_var1 = 0x20; + call_libc (); + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie) +{ + call_libc (); + *cookie = (uintptr_t) map; + return 0; +} + +void +la_activity (uintptr_t* cookie, unsigned int flag) +{ + if (tls_var0 != 0x1 || tls_var1 != 0x20) + abort (); + call_libc (); +} + +void +la_preinit (uintptr_t* cookie) +{ + call_libc (); +} diff --git a/include/link.h b/include/link.h index ebd0f511e2..aca6fa58dc 100644 --- a/include/link.h +++ b/include/link.h @@ -190,6 +190,8 @@ struct link_map unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls) should be called on this link map when relocation finishes. */ + unsigned int l_dont_set_tls_static:1; /* Non zero if static TLS setup should + not be initialized. */ unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */ unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module is interested in the PLT interception.*/ From patchwork Fri Jul 30 19:47:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44524 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AA325384F00D for ; Fri, 30 Jul 2021 19:52:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA325384F00D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674753; bh=d2gw2IJoPqhx9T4jHSH/E9BB7eWzXbb/GLzysopG29A=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=UP4KazKA/kDKz2Ct5lq0+cMZuJ0JXTSUY6RNxMosXJm6/JzcBabp44Xek3x7KfZOb t6C9cshsoM+S1Luo6hwgZzS+TWvfms5K8wYBBgZHTfxWL/HBo3uLHowT5UAzsEKIfz 5AuJpXYyTsBucNdIYKpfYq8tmU1wxy4DCDd+vmCA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id DC8C6398203B for ; Fri, 30 Jul 2021 19:47:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DC8C6398203B Received: by mail-pl1-x629.google.com with SMTP id d1so12362018pll.1 for ; Fri, 30 Jul 2021 12:47:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=d2gw2IJoPqhx9T4jHSH/E9BB7eWzXbb/GLzysopG29A=; b=nPb29Sj9PYGuK18Lp70f1zncLcKsKIxKz1vVgqWOIKJgaDFyiJdArbeKUtPsJD/p6b yKlhPLEVBHMZ969YSC3b4jKIi6a9+EMo31+CLWYzXAAknJ+nJE2Y2tXmCm/w3S1sAcQj yGvHFN9ucrx0QW5L7pF/q3vFyv48z4dDG4NzhMR8jV3Nquzd7mbbTT32IpUDtZGojTal URWYNpNuHN4+iW6+qhu035h5mnFVDSlfYN5pUP5WUhbe1juFozFlxs0yvEaz8Q2NqX5z VniBDuUNoSyNy5bsPcbu891ZGXi63fhUbVHL86K9UpXGomqoidH/OXSQPMEvC5gfmIqe llqQ== X-Gm-Message-State: AOAM532Td3vhZIygOt9hCzAw2FB2+Tsukj4gdm2piPOccHDIb3MV7KFh 2HYObZV9rRTKVfDqm06UNx5Tnv+VzlKq8Q== X-Google-Smtp-Source: ABdhPJwS0hhpnbiDrx21ldQd822sgds8WlnTYpLV/lCaTwcYhvjGdibzCQZiZbFKHtP64Vv30GA4iQ== X-Received: by 2002:a17:902:b717:b029:11a:fae3:ba7c with SMTP id d23-20020a170902b717b029011afae3ba7cmr2574281pls.28.1627674456797; Fri, 30 Jul 2021 12:47:36 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:36 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 06/20] elf: Add _dl_audit_objopen Date: Fri, 30 Jul 2021 16:47:01 -0300 Message-Id: <20210730194715.881900-7-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_objopen() audit callback. No function change, checked on x86_64-linux-gnu. --- elf/Makefile | 3 ++- elf/dl-audit.c | 42 ++++++++++++++++++++++++++++++++++++++ elf/dl-load.c | 17 +-------------- elf/rtld.c | 23 ++------------------- sysdeps/generic/ldsodefs.h | 5 +++++ 5 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 elf/dl-audit.c diff --git a/elf/Makefile b/elf/Makefile index 78ab9f2228..c6c97efd8c 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -35,7 +35,8 @@ dl-routines = $(addprefix dl-,load lookup object reloc deps \ execstack open close trampoline \ exception sort-maps lookup-direct \ call-libc-early-init write \ - thread_gscope_wait tls_init_tp) + thread_gscope_wait tls_init_tp \ + audit) ifeq (yes,$(use-ldconfig)) dl-routines += dl-cache endif diff --git a/elf/dl-audit.c b/elf/dl-audit.c new file mode 100644 index 0000000000..24d8557f18 --- /dev/null +++ b/elf/dl-audit.c @@ -0,0 +1,42 @@ +/* Audit common functions. + 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 + +#ifdef SHARED +void +_dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit) +{ + if (__glibc_likely (GLRO(dl_naudit) == 0) + || (check_audit && GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)) + return; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->objopen != NULL) + { + struct auditstate *state = link_map_audit_state (l, cnt); + state->bindflags = afct->objopen (l, nsid, &state->cookie); + l->l_audit_any_plt |= state->bindflags != 0; + } + + afct = afct->next; + } +} +#endif diff --git a/elf/dl-load.c b/elf/dl-load.c index 433a59191a..c0b68638c0 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1512,22 +1512,7 @@ cannot enable executable stack as shared object requires"); #ifdef SHARED /* Auditing checkpoint: we have a new object. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0) - && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->objopen != NULL) - { - struct auditstate *state = link_map_audit_state (l, cnt); - state->bindflags = afct->objopen (l, nsid, &state->cookie); - l->l_audit_any_plt |= state->bindflags != 0; - } - - afct = afct->next; - } - } + _dl_audit_objopen (l, nsid, true); #endif return l; diff --git a/elf/rtld.c b/elf/rtld.c index 1312378b5f..8008570f82 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1057,25 +1057,6 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); dlmargs.map->l_dont_set_tls_static = 1; } -/* Notify the the audit modules that the object MAP has already been - loaded. */ -static void -notify_audit_modules_of_loaded_object (struct link_map *map) -{ - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->objopen != NULL) - { - struct auditstate *state = link_map_audit_state (map, cnt); - state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie); - map->l_audit_any_plt |= state->bindflags != 0; - } - - afct = afct->next; - } -} - /* Load all audit modules. */ static void load_audit_modules (struct link_map *main_map, struct audit_list *audit_list) @@ -1094,8 +1075,8 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list) program and the dynamic linker itself). */ if (GLRO(dl_naudit) > 0) { - notify_audit_modules_of_loaded_object (main_map); - notify_audit_modules_of_loaded_object (&GL(dl_rtld_map)); + _dl_audit_objopen (main_map, LM_ID_BASE, false); + _dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE, false); } } diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 9c15259236..3432bcd693 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1346,6 +1346,11 @@ link_map_audit_state (struct link_map *l, size_t index) return &base[index]; } } + +/* Call the la_objopen() from the audit modules for the link_map L on the + namespace identification NSID. If CHECK_AUDIT is set it will also check + if main mapping of the namespace is an audit modules. */ +void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit); #endif /* SHARED */ #if PTHREAD_IN_LIBC && defined SHARED From patchwork Fri Jul 30 19:47:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44525 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 242113983046 for ; Fri, 30 Jul 2021 19:53:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 242113983046 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674805; bh=Um1/+d8J9jrXyPSXflhKBY2tpC9WPBhc7hXxH34fWE8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=mYHLh0aWCN8DxaVyjxsZocDT7tr+aYd/aQCOGtaDTqa+KX+IAesYFoud8wD2w2yvI 9QahhVP4OjaMX9R4xWSwYBq4DDfvW0sZnPuj8S1h18Uueg9h4wol+5d6DMuvekJbPa /fmdmol9lkWjM22aIohmnqWeBTJgzO0X7zG57uVg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id 89D7D384F00D for ; Fri, 30 Jul 2021 19:47:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 89D7D384F00D Received: by mail-pl1-x630.google.com with SMTP id e5so12322186pld.6 for ; Fri, 30 Jul 2021 12:47:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Um1/+d8J9jrXyPSXflhKBY2tpC9WPBhc7hXxH34fWE8=; b=CVigHfEG6uiNvBHBwxhfyjRK0gPpwU+jtTF+nuo4Xs/8jH4ideOpJZRFOLg0NIw05k UGrr43J3p6fFr0PLwIk0EVD8a9Sfm8K6ZTvDNo1jgTn+IX5BgAhtW7aM0KdyWmsguiq2 KlIVLedeOy/eFAMciuW5XLdtwi5zdnduIv8CHqcFprSggJYez1wQgs8JQ9OkC397FRhk jPIGFxzdmnwIIEhFo3xRxMxxHcvqcPbFoYjZFDWiUZ6oV9oN8dqJl+v6Ak+2fCfxDzIE AeqrU/H4xh3eIcJTGIn8u7bKpBZcAbiUzOr3pubbyTyBZIXRBI01Qc0dzqyG6UUvvVAP axFw== X-Gm-Message-State: AOAM531rD8/qrOu005IPMuJCn6btmdeeSF+mgDSGf0XrkMZVFlUIfRmA VEH/UtKvUtlvi6u/AX/WL4a/uqqNFLrBRQ== X-Google-Smtp-Source: ABdhPJzicsCVM9iv8Bu/Vrbyim+R8NMI4EX7lw1L9b2eZRStNdH1yTHIbEzNgifR5SjoEZ6qciS2fQ== X-Received: by 2002:a05:6a00:b46:b029:334:54db:af17 with SMTP id p6-20020a056a000b46b029033454dbaf17mr4199642pfo.26.1627674458423; Fri, 30 Jul 2021 12:47:38 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:38 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 07/20] elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid Date: Fri, 30 Jul 2021 16:47:02 -0300 Message-Id: <20210730194715.881900-8-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_activity() audit callback. No function change, checked on x86_64-linux-gnu. --- elf/dl-audit.c | 23 ++++++++++++++++ elf/dl-close.c | 54 +++++++------------------------------- elf/dl-load.c | 28 +++++--------------- elf/dl-open.c | 20 +------------- elf/rtld.c | 31 ++-------------------- sysdeps/generic/ldsodefs.h | 7 +++++ 6 files changed, 48 insertions(+), 115 deletions(-) diff --git a/elf/dl-audit.c b/elf/dl-audit.c index 24d8557f18..5fbc76a36c 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -19,6 +19,29 @@ #include #ifdef SHARED +void +_dl_audit_activity_map (struct link_map *l, int action) +{ + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->activity != NULL) + afct->activity (&link_map_audit_state (l, cnt)->cookie, action); + afct = afct->next; + } +} + +void +_dl_audit_activity_nsid (Lmid_t nsid, int action) +{ + struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; + if (__glibc_likely (GLRO(dl_naudit) == 0) + || head == NULL || head->l_auditing) + return; + + _dl_audit_activity_map (head, action); +} + void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit) { diff --git a/elf/dl-close.c b/elf/dl-close.c index f39001cab9..744621b11f 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -478,25 +478,7 @@ _dl_close_worker (struct link_map *map, bool force) #ifdef SHARED /* Auditing checkpoint: we will start deleting objects. */ - if (__glibc_unlikely (do_audit)) - { - struct link_map *head = ns->_ns_loaded; - struct audit_ifaces *afct = GLRO(dl_audit); - /* Do not call the functions for any auditing object. */ - if (head->l_auditing == 0) - { - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - { - struct auditstate *state = link_map_audit_state (head, cnt); - afct->activity (&state->cookie, LA_ACT_DELETE); - } - - afct = afct->next; - } - } - } + _dl_audit_activity_nsid (nsid, LA_ACT_DELETE); #endif /* Notify the debugger we are about to remove some loaded objects. */ @@ -785,32 +767,14 @@ _dl_close_worker (struct link_map *map, bool force) } #ifdef SHARED - /* Auditing checkpoint: we have deleted all objects. */ - if (__glibc_unlikely (do_audit)) - { - struct link_map *head = ns->_ns_loaded; - /* If head is NULL, the namespace has become empty, and the - audit interface does not give us a way to signal - LA_ACT_CONSISTENT for it because the first loaded module is - used to identify the namespace. - - Furthermore, do not notify auditors of the cleanup of a - failed audit module loading attempt. */ - if (head != NULL && head->l_auditing == 0) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - { - struct auditstate *state = link_map_audit_state (head, cnt); - afct->activity (&state->cookie, LA_ACT_CONSISTENT); - } - - afct = afct->next; - } - } - } + /* Auditing checkpoint: we have deleted all objects. If head is NULL, the + namespace has become empty, and the audit interface does not give us a + way to signal LA_ACT_CONSISTENT for it because the first loaded module + is used to identify the namespace. + + Furthermore, do not notify auditors of the cleanup of a failed audit + module loading attempt. */ + _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT); #endif if (__builtin_expect (ns->_ns_loaded == NULL, 0) diff --git a/elf/dl-load.c b/elf/dl-load.c index c0b68638c0..ecd64d2400 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1057,28 +1057,12 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, if (r->r_state == RT_CONSISTENT) { #ifdef SHARED - /* Auditing checkpoint: we are going to add new objects. */ - if ((mode & __RTLD_AUDIT) == 0 - && __glibc_unlikely (GLRO(dl_naudit) > 0)) - { - struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; - /* Do not call the functions for any auditing object and also do not - try to call auditing functions if the namespace is currently - empty. This happens when opening the first DSO in a new - namespace. */ - if (head != NULL && head->l_auditing == 0) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - afct->activity (&link_map_audit_state (head, cnt)->cookie, - LA_ACT_ADD); - - afct = afct->next; - } - } - } + /* Auditing checkpoint: we are going to add new objects. Do not call + the functions for any auditing object and also do not try to call + auditing functions if the namespace is currently empty. This + happens when opening the first DSO in a new namespace. */ + if ((mode & __RTLD_AUDIT) == 0) + _dl_audit_activity_nsid (nsid, LA_ACT_ADD); #endif /* Notify the debugger we have added some objects. We need to diff --git a/elf/dl-open.c b/elf/dl-open.c index f25340968f..dba36f2c10 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -608,25 +608,7 @@ dl_open_worker (void *a) #ifdef SHARED /* Auditing checkpoint: we have added all objects. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) - { - struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded; - /* Do not call the functions for any auditing object. */ - if (head->l_auditing == 0) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - { - struct auditstate *state = link_map_audit_state (head, cnt); - afct->activity (&state->cookie, LA_ACT_CONSISTENT); - } - - afct = afct->next; - } - } - } + _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); #endif /* Notify the debugger all new objects are now ready to go. */ diff --git a/elf/rtld.c b/elf/rtld.c index 8008570f82..1cbaaa2124 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1760,18 +1760,7 @@ dl_main (const ElfW(Phdr) *phdr, /* Auditing checkpoint: we are ready to signal that the initial map is being constructed. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - afct->activity (&link_map_audit_state (main_map, cnt)->cookie, - LA_ACT_ADD); - - afct = afct->next; - } - } + _dl_audit_activity_map (main_map, LA_ACT_ADD); /* We have two ways to specify objects to preload: via environment variable and via the file /etc/ld.so.preload. The latter can also @@ -2452,23 +2441,7 @@ dl_main (const ElfW(Phdr) *phdr, #ifdef SHARED /* Auditing checkpoint: we have added all objects. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) - { - struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - /* Do not call the functions for any auditing object. */ - if (head->l_auditing == 0) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - afct->activity (&link_map_audit_state (head, cnt)->cookie, - LA_ACT_CONSISTENT); - - afct = afct->next; - } - } - } + _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT); #endif /* Notify the debugger all new objects are now ready to go. We must re-get diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 3432bcd693..013f62c415 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1347,6 +1347,13 @@ link_map_audit_state (struct link_map *l, size_t index) } } +/* Call the la_activity() from the audit modules from the link map L + and issues the ACTION argument. */ +void _dl_audit_activity_map (struct link_map *l, int action) + attribute_hidden; +/* Call the la_activity() from the audit modules from the link map + from the namespace NSSID and issues the ACTION argument. */ +void _dl_audit_activity_nsid (Lmid_t nsid, int action); /* Call the la_objopen() from the audit modules for the link_map L on the namespace identification NSID. If CHECK_AUDIT is set it will also check if main mapping of the namespace is an audit modules. */ From patchwork Fri Jul 30 19:47:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44526 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B3AD63983053 for ; Fri, 30 Jul 2021 19:54:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B3AD63983053 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674849; bh=4c1r5xypGHsah0c6t0fyRIhTfxSDN0ByOjMfUExMNNQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=H4Qh8Ni3VTgf07aK9Wz6pTl/2L4h+vG4inBj9II0ks3f2Hsl86qT1yvXJRwqYTXCd /JxmDIPlbPbzSzn6D4uhuXylxcu4kBBknaTbFRpH/feSBSIauKIVTLmKgIgoEGRwXH ChO+yiLQwJyCOpnS2satdZeDoWMAcDJ79DYj0vjU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by sourceware.org (Postfix) with ESMTPS id 2971839730C2 for ; Fri, 30 Jul 2021 19:47:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2971839730C2 Received: by mail-pj1-x102d.google.com with SMTP id a4-20020a17090aa504b0290176a0d2b67aso22343132pjq.2 for ; Fri, 30 Jul 2021 12:47:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4c1r5xypGHsah0c6t0fyRIhTfxSDN0ByOjMfUExMNNQ=; b=f4jM7sNBMUmf8PIkPPrUH0qaG0w3LQtaEC7sQcVEGAotO1FsYfgBidvp7/y9aEFptm rMpN8W3q9u+BMBhoBacm2H5wfOHOeAc+fxMCYg9F2kw1iV5rIZJq8p1g31XEvCWf0Bxk 66B+MjC8lIpcJGO3+6bLZvy7b/PRA9yL0KwziqtxiivgQqhsWsP978c3ijWYhAHgBvAz LQBUpetOMbmbo7MCrFhqwycnfq0tcxkonlprf3WeZ/Mac8RbueZwxd7/I+Ju6Y6rHNaN bERFdMLTcxff8wXw1eVntRuIpPHj5CiO4dhpAS2mEs7qAyCGnFrBevb4mRhNtxiAjhqe 3d4A== X-Gm-Message-State: AOAM5339LAep2kyOTHFzqrBDJL/DC8lBJlT9iaNw/pm4OBDjJVGiVtsw zRt39eU88R91wqFZclCmC11hxfNtPmFtUw== X-Google-Smtp-Source: ABdhPJwHjLscJG6AxmVGPhOsX48r2FyYTKir1Hd0dUj5a+LgQie2G+c7F9wgeWFmUVJ0q3cBwJ4m5w== X-Received: by 2002:a62:7b83:0:b029:3a9:d407:a383 with SMTP id w125-20020a627b830000b02903a9d407a383mr4344491pfc.27.1627674460040; Fri, 30 Jul 2021 12:47:40 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:39 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 08/20] elf: Add _dl_audit_objsearch Date: Fri, 30 Jul 2021 16:47:03 -0300 Message-Id: <20210730194715.881900-9-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_objsearch() audit callback. No function change, checked on x86_64-linux-gnu. --- elf/dl-audit.c | 37 +++++++++++++++++++++++ elf/dl-load.c | 61 ++++---------------------------------- sysdeps/generic/ldsodefs.h | 2 ++ 3 files changed, 44 insertions(+), 56 deletions(-) diff --git a/elf/dl-audit.c b/elf/dl-audit.c index 5fbc76a36c..de85ef1ddd 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -42,6 +42,43 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action) _dl_audit_activity_map (head, action); } +bool +_dl_audit_objsearch (const char **name, const char **origname, + struct link_map *l, unsigned int code) +{ + if (__glibc_likely (GLRO(dl_naudit) == 0) + || l == NULL || l->l_auditing + || code == 0) + return true; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->objsearch != NULL) + { + const char *before = *name; + struct auditstate *state = link_map_audit_state (l, cnt); + *name = afct->objsearch (*name, &state->cookie, code); + if (*name == NULL) + return false; + + if (origname != NULL && before != *name + && strcmp (before, *name) != 0) + { + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("audit changed filename %s -> %s\n", + before, *name); + + if (*origname == NULL) + *origname = before; + } + } + afct = afct->next; + } + + return true; +} + void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit) { diff --git a/elf/dl-load.c b/elf/dl-load.c index ecd64d2400..8f8971de29 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1592,33 +1592,8 @@ open_verify (const char *name, int fd, #ifdef SHARED /* Give the auditing libraries a chance. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0 - && loader->l_auditing == 0) - { - const char *original_name = name; - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->objsearch != NULL) - { - struct auditstate *state = link_map_audit_state (loader, cnt); - name = afct->objsearch (name, &state->cookie, whatcode); - if (name == NULL) - /* Ignore the path. */ - return -1; - } - - afct = afct->next; - } - - if (fd != -1 && name != original_name && strcmp (name, original_name)) - { - /* An audit library changed what we're supposed to open, - so FD no longer matches it. */ - __close_nocancel (fd); - fd = -1; - } - } + if (!_dl_audit_objsearch (&name, NULL, loader, whatcode)) + return -1; #endif if (fd == -1) @@ -2056,36 +2031,10 @@ _dl_map_object (struct link_map *loader, const char *name, #ifdef SHARED /* Give the auditing libraries a chance to change the name before we try anything. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0) - && (loader == NULL || loader->l_auditing == 0)) + if (!_dl_audit_objsearch (&name, &origname, loader, LA_SER_ORIG)) { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->objsearch != NULL) - { - const char *before = name; - struct auditstate *state = link_map_audit_state (loader, cnt); - name = afct->objsearch (name, &state->cookie, LA_SER_ORIG); - if (name == NULL) - { - /* Do not try anything further. */ - fd = -1; - goto no_file; - } - if (before != name && strcmp (before, name) != 0) - { - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf ("audit changed filename %s -> %s\n", - before, name); - - if (origname == NULL) - origname = before; - } - } - - afct = afct->next; - } + fd = -1; + goto no_file; } #endif diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 013f62c415..e920e1215b 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1347,6 +1347,8 @@ link_map_audit_state (struct link_map *l, size_t index) } } +bool _dl_audit_objsearch (const char **name, const char **origname, + struct link_map *l, unsigned int code); /* Call the la_activity() from the audit modules from the link map L and issues the ACTION argument. */ void _dl_audit_activity_map (struct link_map *l, int action) From patchwork Fri Jul 30 19:47:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44527 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 725343982429 for ; Fri, 30 Jul 2021 19:54:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 725343982429 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674894; bh=lo+Uatjf/3/ZvncOgHRtn0zQtB0IRJGCR8qkMQPG74s=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=OajDFCsttZkux+npsZNNFPeMEjsYGDzpCOe1jdo8kJXv9suOZW+cXvOmT+ch4U344 Bf4IXV67WZKGAZDjWDeYSsaoGn0eBSsno4A+BCpfFymZ8JdzufjuMSIoyo5JW876Pg xugi7KfIESwYNYRp0xjGEMccMXfQnYPxMsa7QiFU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id BD57F397EC13 for ; Fri, 30 Jul 2021 19:47:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BD57F397EC13 Received: by mail-pj1-x102c.google.com with SMTP id j18-20020a17090aeb12b029017737e6c349so9560626pjz.0 for ; Fri, 30 Jul 2021 12:47:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lo+Uatjf/3/ZvncOgHRtn0zQtB0IRJGCR8qkMQPG74s=; b=RcJCFASRSuz3NVjqsH565xG0/YJWg41M7sWPstw1s+A1qADn5s4iRwMsaKwYi4Q9Mp GSJyJ2/SfX9tqgdmiJmDkrJZXURaK5GjSGvczZQ2JaERhW70ZWvSjtwMGoI/yLPpAFYZ kqeFOynTY/urJT3C5VUwONeF9V/8wTepw47zXxOSKNljRzRwGhqYQxYFcdLljPo2CMsO 0W4BiUGGlX+Eco9Aj22+M933RW7lk03ccjDYwQapLih8wa0I3TgCxZ7/Zi4Hvv6VGHyu oyFN0ySw68EQXcprW90Q5maxI9ehfG73fO7TYzgTKwAwUGpyeqinzk9nSIgbUSe72TFj zm4Q== X-Gm-Message-State: AOAM533OEnefRWjJM9r60Zwo4XeUDS8H05FBzynApPLsBEOcBPaIagz6 iLjenOkeV+Vm3kwPaFrtz3phj5TLf+keAA== X-Google-Smtp-Source: ABdhPJxYmmE2awmEzBrxv9SjiAaYDIfzAfo1ejxPfxWypkWXrMB1ZndS4aFJ2elbIwzDBHRTSKB7DA== X-Received: by 2002:a63:e547:: with SMTP id z7mr2907188pgj.65.1627674461672; Fri, 30 Jul 2021 12:47:41 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:41 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 09/20] elf: Add _dl_audit_objclose Date: Fri, 30 Jul 2021 16:47:04 -0300 Message-Id: <20210730194715.881900-10-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_objclose() audit callback. No function change, checked on x86_64-linux-gnu. --- elf/dl-audit.c | 21 +++++++++++++++++++++ elf/dl-close.c | 20 +------------------- elf/dl-fini.c | 16 +--------------- sysdeps/generic/ldsodefs.h | 3 +++ 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/elf/dl-audit.c b/elf/dl-audit.c index de85ef1ddd..ef34ff761c 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -99,4 +99,25 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit) afct = afct->next; } } + +void +_dl_audit_objclose (struct link_map *l, Lmid_t nsid) +{ + if (__glibc_likely (GLRO(dl_naudit) == 0) + || GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) + return; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->objclose != NULL) + { + struct auditstate *state= link_map_audit_state (l, cnt); + /* Return value is ignored. */ + afct->objclose (&state->cookie); + } + + afct = afct->next; + } +} #endif diff --git a/elf/dl-close.c b/elf/dl-close.c index 744621b11f..44484efd32 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -266,9 +266,6 @@ _dl_close_worker (struct link_map *map, bool force) used + (nsid == LM_ID_BASE), true); /* Call all termination functions at once. */ -#ifdef SHARED - bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing; -#endif bool unload_any = false; bool scope_mem_left = false; unsigned int unload_global = 0; @@ -302,22 +299,7 @@ _dl_close_worker (struct link_map *map, bool force) #ifdef SHARED /* Auditing checkpoint: we remove an object. */ - if (__glibc_unlikely (do_audit)) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->objclose != NULL) - { - struct auditstate *state - = link_map_audit_state (imap, cnt); - /* Return value is ignored. */ - (void) afct->objclose (&state->cookie); - } - - afct = afct->next; - } - } + _dl_audit_objclose (imap, nsid); #endif /* This object must not be used anymore. */ diff --git a/elf/dl-fini.c b/elf/dl-fini.c index 6dbdfe4b3e..35a5471dcd 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -147,21 +147,7 @@ _dl_fini (void) #ifdef SHARED /* Auditing checkpoint: another object closed. */ - if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0)) - { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->objclose != NULL) - { - struct auditstate *state - = link_map_audit_state (l, cnt); - /* Return value is ignored. */ - (void) afct->objclose (&state->cookie); - } - afct = afct->next; - } - } + _dl_audit_objclose (l, ns); #endif } diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index e920e1215b..fa56d43678 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1360,6 +1360,9 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action); namespace identification NSID. If CHECK_AUDIT is set it will also check if main mapping of the namespace is an audit modules. */ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit); +/* Call the la_objclose () from audit modules for the link_map L on the + namespace identification NSID. */ +void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); #endif /* SHARED */ #if PTHREAD_IN_LIBC && defined SHARED From patchwork Fri Jul 30 19:47:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44528 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 404A1398242A for ; Fri, 30 Jul 2021 19:55:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 404A1398242A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674945; bh=/+qcGGIYCycKPWd7eNxxGlaP8gcqtlAdl5kbucU9eGk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=HxLDGNrm5kUvybqc9sDZ07E+Bt2iQBNXCwn/lKtPNxgxYqeWWb/17m1DXzGi4/bCN xcpCrNLedSJ+LIV48DS84JF3IN/KSHByQZapu+1iv83qSoRDhSElQ2CJW7oFJNoriO ZTilY+5xRsZmMP8Cb+8iKy/lag6xvh/6G/oBQPU4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by sourceware.org (Postfix) with ESMTPS id 8CBF6397EC2B for ; Fri, 30 Jul 2021 19:47:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8CBF6397EC2B Received: by mail-pj1-x1031.google.com with SMTP id g23-20020a17090a5797b02901765d605e14so15878231pji.5 for ; Fri, 30 Jul 2021 12:47:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/+qcGGIYCycKPWd7eNxxGlaP8gcqtlAdl5kbucU9eGk=; b=uXNvTdn4CLE3d/a9tacNxZSO2pIIpAZkwC42EncY/F0aPk+/rlxTWJ3Jk1e46N67uK ROU8i62mdWr15UmwjwLMEu6QPRtJfrzXbMzQJ0G98eo9xbhU1QKIscDQN9ilFowWbxil ZcWf9wO8TBNO7n0W+1j88ematpzt2uMEDnvibWFQyuctYCvra14zFxc2KgOLS/PZdSZC iNfueBZpCOJQU8/z6Nd8Uxpq189G4YebAqq2hcLm6Qzohym1aziUgqEaSIdYQQZonlSr jGJxlJKGxf7bi/WxFs2a5sgmQ3LvkEqAD/aFEBKas2+TgFJtLaJuWXdc5csuarwXF8U2 B0tg== X-Gm-Message-State: AOAM532GDKdITsH8o3cQ/rr0tQ/Psg2YHTHzQQj+ckfD9DFWQpYhFwB0 d++uSX+lUOsALCg+vy1G8UI0HHAE0ZGTKg== X-Google-Smtp-Source: ABdhPJzg3KeRZh0lyd15cdTMWs8I4mPSgqu0efQS61LfMNM+cBxmqx1ranRLo4wa/zv4lq4DHRup+w== X-Received: by 2002:a63:3c5d:: with SMTP id i29mr3709443pgn.147.1627674463425; Fri, 30 Jul 2021 12:47:43 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:43 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 10/20] elf: Add _dl_audit_symbind_alt and _dl_audit_symbind Date: Fri, 30 Jul 2021 16:47:05 -0300 Message-Id: <20210730194715.881900-11-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_symbind{32,64}() audit callback. No function change, checked on x86_64-linux-gnu. --- elf/Versions | 1 + elf/dl-audit.c | 122 +++++++++++++++++++++++++++++++++++++ elf/dl-runtime.c | 77 ----------------------- elf/dl-sym-post.h | 47 +------------- sysdeps/generic/ldsodefs.h | 14 +++++ 5 files changed, 138 insertions(+), 123 deletions(-) diff --git a/elf/Versions b/elf/Versions index 775aab62af..25e91339b5 100644 --- a/elf/Versions +++ b/elf/Versions @@ -55,6 +55,7 @@ ld { _dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info; _dl_deallocate_tls; _dl_make_stack_executable; _dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf; + _dl_audit_symbind_alt; _rtld_global; _rtld_global_ro; # Only here for gdb while a better method is developed. diff --git a/elf/dl-audit.c b/elf/dl-audit.c index ef34ff761c..8e4c65fdaf 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -16,6 +16,7 @@ License along with the GNU C Library; if not, see . */ +#include #include #ifdef SHARED @@ -120,4 +121,125 @@ _dl_audit_objclose (struct link_map *l, Lmid_t nsid) afct = afct->next; } } + +void +_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value, + lookup_t result) +{ + if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0) + return; + + const char *strtab = (const char *) D_PTR (result, l_info[DT_STRTAB]); + /* Compute index of the symbol entry in the symbol table of the DSO with + the definition. */ + unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, l_info[DT_SYMTAB])); + + unsigned int altvalue = 0; + /* Synthesize a symbol record where the st_value field is the result. */ + ElfW(Sym) sym = *ref; + sym.st_value = (ElfW(Addr)) *value; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + struct auditstate *match_audit = link_map_audit_state (l, cnt); + struct auditstate *result_audit = link_map_audit_state (result, cnt); + if (afct->symbind != NULL + && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0 + || ((result_audit->bindflags & LA_FLG_BINDTO) + != 0))) + { + unsigned int flags = altvalue | LA_SYMB_DLSYM; + uintptr_t new_value = afct->symbind (&sym, ndx, + &match_audit->cookie, + &result_audit->cookie, + &flags, strtab + ref->st_name); + if (new_value != (uintptr_t) sym.st_value) + { + altvalue = LA_SYMB_ALTVALUE; + sym.st_value = new_value; + } + + afct = afct->next; + } + + *value = (void *) sym.st_value; + } +} +rtld_hidden_def (_dl_audit_symbind_alt) + +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) +{ + 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])); + + 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; + return; + } + + /* Synthesize a symbol record where the st_value field is the result. */ + ElfW(Sym) sym = *defsym; + sym.st_value = DL_FIXUP_VALUE_ADDR (*value); + + /* Keep track whether there is any interest in tracing the call in the lower + 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; + + const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); + + unsigned int flags = 0; + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + /* XXX Check whether both DSOs must request action or only one */ + struct auditstate *l_state = link_map_audit_state (l, cnt); + struct auditstate *result_state = link_map_audit_state (result, cnt); + if ((l_state->bindflags & LA_FLG_BINDFROM) != 0 + && (result_state->bindflags & LA_FLG_BINDTO) != 0) + { + 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); + if (new_value != (uintptr_t) sym.st_value) + { + flags |= LA_SYMB_ALTVALUE; + sym.st_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)); + } + 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)); + afct = afct->next; + } + + reloc_result->flags = flags; + *value = DL_FIXUP_ADDR_VALUE (sym.st_value); +} #endif diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 29031099f5..680e66a6d6 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -43,83 +43,6 @@ # define ARCH_FIXUP_ATTRIBUTE #endif -#ifdef SHARED -static 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) -{ - 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])); - - 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; - return; - } - - /* Synthesize a symbol record where the st_value field is the result. */ - ElfW(Sym) sym = *defsym; - sym.st_value = DL_FIXUP_VALUE_ADDR (*value); - - /* Keep track whether there is any interest in tracing the call in the lower - 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; - - const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); - - unsigned int flags = 0; - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - /* XXX Check whether both DSOs must request action or only one */ - struct auditstate *l_state = link_map_audit_state (l, cnt); - struct auditstate *result_state = link_map_audit_state (result, cnt); - - if ((l_state->bindflags & LA_FLG_BINDFROM) != 0 - && (result_state->bindflags & LA_FLG_BINDTO) != 0) - { - 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); - if (new_value != (uintptr_t) sym.st_value) - { - flags |= LA_SYMB_ALTVALUE; - sym.st_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)); - } - 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)); - afct = afct->next; - } - - reloc_result->flags = flags; - *value = DL_FIXUP_ADDR_VALUE (sym.st_value); -} -#endif /* This function is called through a special trampoline from the PLT the first time each PLT entry is called. We must perform the relocation diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h index d68c2d2b1c..a11095d3e8 100644 --- a/elf/dl-sym-post.h +++ b/elf/dl-sym-post.h @@ -52,54 +52,9 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value, tell us whether further auditing is wanted. */ if (__glibc_unlikely (GLRO(dl_naudit) > 0)) { - const char *strtab = (const char *) D_PTR (result, - l_info[DT_STRTAB]); - /* Compute index of the symbol entry in the symbol table of - the DSO with the definition. */ - unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, - l_info[DT_SYMTAB])); - if (match == NULL) match = _dl_sym_find_caller_link_map (caller); - - if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0) - { - unsigned int altvalue = 0; - struct audit_ifaces *afct = GLRO(dl_audit); - /* Synthesize a symbol record where the st_value field is - the result. */ - ElfW(Sym) sym = *ref; - sym.st_value = (ElfW(Addr)) value; - - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - struct auditstate *match_audit - = link_map_audit_state (match, cnt); - struct auditstate *result_audit - = link_map_audit_state (result, cnt); - if (afct->symbind != NULL - && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0 - || ((result_audit->bindflags & LA_FLG_BINDTO) - != 0))) - { - unsigned int flags = altvalue | LA_SYMB_DLSYM; - uintptr_t new_value - = afct->symbind (&sym, ndx, - &match_audit->cookie, - &result_audit->cookie, - &flags, strtab + ref->st_name); - if (new_value != (uintptr_t) sym.st_value) - { - altvalue = LA_SYMB_ALTVALUE; - sym.st_value = new_value; - } - } - - afct = afct->next; - } - - value = (void *) sym.st_value; - } + _dl_audit_symbind_alt (match, ref, &value, result); } #endif return value; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index fa56d43678..f7db886fc0 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1363,6 +1363,20 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit); /* Call the la_objclose () from audit modules for the link_map L on the namespace identification NSID. */ void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); +/* Call the la_symbind32() or la_symbind64() from audit modules for the + link_map L. The RELOC_RESULT is the entry from link_map::l_reloc_result used + to keep track of the binding actions set by the audir modules, while DEFSYM + is the reference used to resolve the target symbol, VALUE is the relocation + result value (which might be overwritten by the callback), and RESULT is the + link_map for the symbol resolved. */ +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); +/* Same as _dl_audit_symbind(), but called from the dlsym(). The flag + LA_SYMB_DLSYM will be set before calling la_symbind() callback. */ +void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, + void **value, lookup_t result); +rtld_hidden_proto (_dl_audit_symbind_alt) #endif /* SHARED */ #if PTHREAD_IN_LIBC && defined SHARED From patchwork Fri Jul 30 19:47:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44529 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6F24B3982438 for ; Fri, 30 Jul 2021 19:56:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F24B3982438 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627674990; bh=LUYDJlkCZkvP29jFdo+fBZ6yO1R5Kl9aYYuWE7Hij1E=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=SWu8ooqLKslTMuejORwt/dYPz5YRHcYXOCeZGStkh3Dgz+rrOKfjzU8PwUtlTIsp9 R2yelSobE7R7aWHvhdAYijyqz1/rTPC4dBPqUlj7co3xGF2LHO3siWLa/xA9/W1Tpi YjAKCSQ7aqrHNie+lWzUqRNVWzmkj+t/sVTjTS/Q= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by sourceware.org (Postfix) with ESMTPS id 1D6FC39730FF for ; Fri, 30 Jul 2021 19:47:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1D6FC39730FF Received: by mail-pl1-x633.google.com with SMTP id u16so3798492ple.2 for ; Fri, 30 Jul 2021 12:47:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LUYDJlkCZkvP29jFdo+fBZ6yO1R5Kl9aYYuWE7Hij1E=; b=liaCkQKoNjTuQTuERJQid/RMYzPEZ7i9Y1DioPTVS3W//hutIFQ4gSVuFTfmiWCmmB lVjJch7bbm2tGXjSn38qr4gVt6rvVZ/4b0IyplJ/6Yh3H4yrCudtFUIev05s0QMQxDpf 0E5iBgR7p3G3rCeyRWLHTAbA35XcGkeaIiWSYimhOFHzNlKvBJWu/EE2nxym87YpNVGJ a/yW6UrnwyioA9wxva0aMdoCkN/WRR7hl/KdgiY3f1rJ5afq5edatE1IJ3eGSjsTCeLc UFJ/+TpAkSDV98PZmx8C8bcKZVfktuepH0JWZAC4GTORsSQZZb4rjK2r4TU25RaPquBl 29dA== X-Gm-Message-State: AOAM531P0cHK6w1TBJm39Jj+QiNFbcKa6QAjpSvyuKG/PdxnJMCnjbrf To2Vyq4GvKTegm2iXraaL+PqMTrE845jFg== X-Google-Smtp-Source: ABdhPJwrZfEeSZPpjGrACZULvcx+nf7jRhLTw44sFPJtY3ILlySBKC48xSxhqMzGagGIBbwyK1om+g== X-Received: by 2002:a63:4b0a:: with SMTP id y10mr3667500pga.437.1627674465057; Fri, 30 Jul 2021 12:47:45 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:44 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 11/20] elf: Add _dl_audit_preinit Date: Fri, 30 Jul 2021 16:47:06 -0300 Message-Id: <20210730194715.881900-12-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_preinit() audit callback. No function change, checked on x86_64-linux-gnu. --- csu/libc-start.c | 23 +++-------------------- elf/Versions | 2 +- elf/dl-audit.c | 15 +++++++++++++++ sysdeps/generic/ldsodefs.h | 2 ++ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/csu/libc-start.c b/csu/libc-start.c index 0350b006fd..d01e57ea59 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -377,32 +377,15 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), /* This is a current program. Use the dynamic segment to find constructors. */ call_init (argc, argv, __environ); -#else /* !SHARED */ - call_init (argc, argv, __environ); -#endif /* SHARED */ -#ifdef SHARED /* Auditing checkpoint: we have a new object. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) - { - struct audit_ifaces *afct = GLRO(dl_audit); - struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->preinit != NULL) - afct->preinit (&link_map_audit_state (head, cnt)->cookie); - - afct = afct->next; - } - } -#endif + _dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded); -#ifdef SHARED if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); -#endif +#else /* !SHARED */ + call_init (argc, argv, __environ); -#ifndef SHARED _dl_debug_initialize (0, LM_ID_BASE); #endif diff --git a/elf/Versions b/elf/Versions index 25e91339b5..bfe1aec293 100644 --- a/elf/Versions +++ b/elf/Versions @@ -55,7 +55,7 @@ ld { _dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info; _dl_deallocate_tls; _dl_make_stack_executable; _dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf; - _dl_audit_symbind_alt; + _dl_audit_symbind_alt; _dl_audit_preinit; _rtld_global; _rtld_global_ro; # Only here for gdb while a better method is developed. diff --git a/elf/dl-audit.c b/elf/dl-audit.c index 8e4c65fdaf..a968cbde16 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -122,6 +122,21 @@ _dl_audit_objclose (struct link_map *l, Lmid_t nsid) } } +void +_dl_audit_preinit (struct link_map *l) +{ + if (__glibc_likely (GLRO(dl_naudit) < 0)) + return; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->preinit != NULL) + afct->preinit (&link_map_audit_state (l, cnt)->cookie); + afct = afct->next; + } +} + void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value, lookup_t result) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index f7db886fc0..4d39888a7b 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1376,6 +1376,8 @@ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, LA_SYMB_DLSYM will be set before calling la_symbind() callback. */ void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value, lookup_t result); +/* Call the la_preinit() from audit modules for the link_map L. */ +void _dl_audit_preinit (struct link_map *l); rtld_hidden_proto (_dl_audit_symbind_alt) #endif /* SHARED */ From patchwork Fri Jul 30 19:47:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44530 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1C95F3983C50 for ; Fri, 30 Jul 2021 19:57:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1C95F3983C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675036; bh=/SC7uS/+NHVu6zDqyDQqL1f7VVvWF+ouJ05IGfuMP9U=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=CFjQsAxLaRA8fCY+7gRT0l8tIVhHRBf9A40ZVnrLZo2EyGxR/tzjMZRI6w3VjTbU3 blrVdbuOwCpaMlt0BIlZzs3H1zxFkUGXm4D0JdXD4cdztruusHXkfhZlzK9QXE2Y5a 0/Dbh6FLlTW/L38sW4SlKUFPigmSk/ktaSnQHy7o= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id B9DE5398202E for ; Fri, 30 Jul 2021 19:47:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B9DE5398202E Received: by mail-pl1-x62d.google.com with SMTP id u2so4061653plg.10 for ; Fri, 30 Jul 2021 12:47:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/SC7uS/+NHVu6zDqyDQqL1f7VVvWF+ouJ05IGfuMP9U=; b=MEfV7NlkXOte+4wp8OdvUEb84Xq/qG5l3wL68p85iG4POqWM1dUO9lKD/K+kj5psv0 0sv65YW/rloZAFAtE7PP3TbhZ8vWDREV/ZpqZZ41Zz5vipjGB0cW335Z+HAwDBicUbKk iSCrDMorJrRR1q84mQc9WBA+mbagnUE3Dz/qCgaxKJhWkA0lz3VemlurBTwszit9ElL8 OWbR8cTbPGV3xA0lbbxFGN7sDX+EYDLeQaGe86s1ndn4f6fZli7X/BVHh3sX5QhMSuwQ stES1u/DxcSHzjWGGH4mJrlqROqeUzWJhSeE28HygU6aMEyYyDsCnTK1U9Z657ag+KdH 4raw== X-Gm-Message-State: AOAM533MO/GFRDiCkFCC4k6O0XlKwBwwnZ+Dm1xEnDY1SiEBJv/5rK44 gj5LzCV0w5acwuvWNJM+bvgZ6mAVzf8a2w== X-Google-Smtp-Source: ABdhPJxIO2On2JtzZwFlUXsH6k73DIKOCdCqupMWPpgXcaP4M891AnfSbemI/e6AsMeUxvWYnnKxxg== X-Received: by 2002:a65:41c7:: with SMTP id b7mr3140419pgq.81.1627674466627; Fri, 30 Jul 2021 12:47:46 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:46 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 12/20] elf: Add _dl_audit_pltenter Date: Fri, 30 Jul 2021 16:47:07 -0300 Message-Id: <20210730194715.881900-13-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_pltenter() audit callback. No function change, checked on x86_64-linux-gnu. --- elf/dl-audit.c | 77 ++++++++++++++++++++++++++++++++++++++ elf/dl-runtime.c | 73 +----------------------------------- sysdeps/generic/ldsodefs.h | 8 ++++ 3 files changed, 86 insertions(+), 72 deletions(-) diff --git a/elf/dl-audit.c b/elf/dl-audit.c index a968cbde16..7d410bc128 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -17,7 +17,9 @@ . */ #include +#include #include +#include #ifdef SHARED void @@ -257,4 +259,79 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, reloc_result->flags = flags; *value = DL_FIXUP_ADDR_VALUE (sym.st_value); } + +void +_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, + DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize) +{ + /* Don't do anything if no auditor wants to intercept this call. */ + if (GLRO(dl_naudit) == 0 + || (reloc_result->enterexit & LA_SYMB_NOPLTENTER)) + return; + + /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been + initialized earlier in this function or in another thread. */ + assert (DL_FIXUP_VALUE_CODE_ADDR (*value) != 0); + ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, + l_info[DT_SYMTAB]) + + reloc_result->boundndx); + + /* Set up the sym parameter. */ + ElfW(Sym) sym = *defsym; + sym.st_value = DL_FIXUP_VALUE_ADDR (*value); + + /* Get the symbol name. */ + const char *strtab = (const void *) D_PTR (reloc_result->bound, + l_info[DT_STRTAB]); + const char *symname = strtab + sym.st_name; + + /* Keep track of overwritten addresses. */ + unsigned int flags = reloc_result->flags; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->ARCH_LA_PLTENTER != NULL + && (reloc_result->enterexit + & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0) + { + long int new_framesize = -1; + struct auditstate *l_state = link_map_audit_state (l, cnt); + struct auditstate *bound_state + = link_map_audit_state (reloc_result->bound, cnt); + uintptr_t new_value + = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx, + &l_state->cookie, &bound_state->cookie, + regs, &flags, symname, &new_framesize); + if (new_value != (uintptr_t) sym.st_value) + { + flags |= LA_SYMB_ALTVALUE; + sym.st_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)) + << (2 * (cnt + 1))); + + if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT + << (2 * (cnt + 1)))) + == 0 && new_framesize != -1 && *framesize != -2) + { + /* If this is the first call providing information, use it. */ + if (*framesize == -1) + *framesize = new_framesize; + /* If two pltenter calls provide conflicting information, use + the larger value. */ + else if (new_framesize != *framesize) + *framesize = MAX (new_framesize, *framesize); + } + } + + afct = afct->next; + } + + *value = DL_FIXUP_ADDR_VALUE (sym.st_value); +} #endif diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 680e66a6d6..4d16957c08 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -351,78 +351,7 @@ _dl_profile_fixup ( #ifdef SHARED /* Auditing checkpoint: report the PLT entering and allow the auditors to change the value. */ - if (GLRO(dl_naudit) > 0 - /* Don't do anything if no auditor wants to intercept this call. */ - && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0) - { - /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been - initialized earlier in this function or in another thread. */ - assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0); - ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, - l_info[DT_SYMTAB]) - + reloc_result->boundndx); - - /* Set up the sym parameter. */ - ElfW(Sym) sym = *defsym; - sym.st_value = DL_FIXUP_VALUE_ADDR (value); - - /* Get the symbol name. */ - const char *strtab = (const void *) D_PTR (reloc_result->bound, - l_info[DT_STRTAB]); - const char *symname = strtab + sym.st_name; - - /* Keep track of overwritten addresses. */ - unsigned int flags = reloc_result->flags; - - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->ARCH_LA_PLTENTER != NULL - && (reloc_result->enterexit - & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0) - { - long int new_framesize = -1; - struct auditstate *l_state = link_map_audit_state (l, cnt); - struct auditstate *bound_state - = link_map_audit_state (reloc_result->bound, cnt); - uintptr_t new_value - = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx, - &l_state->cookie, - &bound_state->cookie, - regs, &flags, symname, - &new_framesize); - if (new_value != (uintptr_t) sym.st_value) - { - flags |= LA_SYMB_ALTVALUE; - sym.st_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)) - << (2 * (cnt + 1))); - - if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT - << (2 * (cnt + 1)))) - == 0 && new_framesize != -1 && framesize != -2) - { - /* If this is the first call providing information, - use it. */ - if (framesize == -1) - framesize = new_framesize; - /* If two pltenter calls provide conflicting information, - use the larger value. */ - else if (new_framesize != framesize) - framesize = MAX (new_framesize, framesize); - } - } - - afct = afct->next; - } - - value = DL_FIXUP_ADDR_VALUE (sym.st_value); - } + _dl_audit_pltenter (l, reloc_result, &value, regs, &framesize); #endif /* Store the frame size information. */ diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 4d39888a7b..32a621ae99 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1379,6 +1379,14 @@ void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, /* Call the la_preinit() from audit modules for the link_map L. */ void _dl_audit_preinit (struct link_map *l); rtld_hidden_proto (_dl_audit_symbind_alt) +/* Call the la_pltenter() arch specific from audit modules for the link_map L. + The RELOC_RESULT is the entry from link_map::l_reloc_result used to keep + track of the binding actions set by the audit modules, while VALUE is the + relocation result value, and REGS is the arch-specific register state + saved, and FRAMESIZE is the frame size pointer passed on the callback. */ +void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, + DL_FIXUP_VALUE_TYPE *value, void *regs, + long int *framesize); #endif /* SHARED */ #if PTHREAD_IN_LIBC && defined SHARED From patchwork Fri Jul 30 19:47:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44531 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9B42C398404D for ; Fri, 30 Jul 2021 19:58:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B42C398404D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675087; bh=2/BBCe+gqw0/8ZjvRFR70C0Cblu+SQRUtbGnQRB0z0Y=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=i+NBYMAmuaYiEdeSDPBodRHp3YdDmikUvBR8nyOIWYD9vKv1WIKRnjFY6Swf8JusX 3Ed2xlNM+byYBshMfyf2p5pwOMWN8Vu4+oZNzsSujGQRI4IVU4yv+7T1QNJfdj7+P2 9v0FnWkbJgf5blnGedyXKW5KDfx06zEdL2aUBwrw= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by sourceware.org (Postfix) with ESMTPS id 9B18A3982032 for ; Fri, 30 Jul 2021 19:47:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9B18A3982032 Received: by mail-pj1-x102e.google.com with SMTP id b6so16732103pji.4 for ; Fri, 30 Jul 2021 12:47:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2/BBCe+gqw0/8ZjvRFR70C0Cblu+SQRUtbGnQRB0z0Y=; b=q6JqwW8nmTax6LYfcRnaM7NcjmDU+WcvVS/41lIe4+6DgPXExhFAwP7w1I25Poa1tq 3zJNeMrZ49RuONUUvpQLr/NZcf4xbpW8xrMUQjNDhxg8Wqz3N93dN1lWhfPPZXw8k7V+ XIkfGUZ8Id2Oog5wqet2nxdnrEb5TqZztgo1Zql82g1VTDLLlDJntiEPuiiohrocNO8J 5EtM+KATQhN7rgTEUBAwwDluG0jYoagaR4/c4F1M8J53q1/fKVTKtznxcCFtrwuAWzGz yDHQlge5dpD80lV2Qpvpkv+wY5VxyoTGpYYXfoORqRuMoenEtwVQO5mGUTTERLuQ/OBc soBg== X-Gm-Message-State: AOAM532UybbIHHurcr5jdtyyu0yRYjYk8lygRzjJbITup0Mt5rxkUdG0 cyT2C93s/0EUWyrc1xYY4bzBrhRH2pHhiw== X-Google-Smtp-Source: ABdhPJwA7CUthByQ1+5jtFQLUTPbIwlWavCzdkK9UPhCat55pgWQaszRqebAAdfP+C9eYMzJidvnwA== X-Received: by 2002:a63:ef02:: with SMTP id u2mr3822805pgh.298.1627674468306; Fri, 30 Jul 2021 12:47:48 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:48 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 13/20] elf: Add _dl_audit_pltexit Date: Fri, 30 Jul 2021 16:47:08 -0300 Message-Id: <20210730194715.881900-14-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" It consolidates the code required to call la_pltexit() audit callback. Two refactoring changes: - ARCH_FIXUP_ATTRIBUTE is renamed to DL_ARCH_FIXUP_ATTRIBUTE and moved to the arch-specific dl-fixup-attribute.h internal header. Currently only i686 requires an specific definition. - _dl_call_pltexit is renamed to _dl_audit_pltexit for all architectures. No function change, checked on x86_64-linux-gnu and on i686-linux-gnu. --- elf/dl-audit.c | 56 ++++++++++++++++++++ elf/dl-runtime.c | 62 ++--------------------- sysdeps/aarch64/dl-trampoline.S | 2 +- sysdeps/alpha/dl-trampoline.S | 8 +-- sysdeps/arm/dl-trampoline.S | 2 +- sysdeps/generic/dl-fixup-attribute.h | 24 +++++++++ sysdeps/generic/ldsodefs.h | 9 ++++ sysdeps/hppa/dl-runtime.c | 2 +- sysdeps/hppa/dl-trampoline.S | 6 +-- sysdeps/i386/dl-fixup-attribute.h | 30 +++++++++++ sysdeps/i386/dl-machine.h | 23 --------- sysdeps/i386/dl-trampoline.S | 2 +- sysdeps/ia64/dl-trampoline.S | 16 +++--- sysdeps/m68k/dl-trampoline.S | 2 +- sysdeps/powerpc/powerpc64/dl-trampoline.S | 4 +- sysdeps/s390/s390-32/dl-trampoline.h | 4 +- sysdeps/s390/s390-64/dl-trampoline.h | 2 +- sysdeps/sh/dl-trampoline.S | 4 +- sysdeps/sparc/sparc32/dl-trampoline.S | 2 +- sysdeps/sparc/sparc64/dl-trampoline.S | 2 +- sysdeps/x86_64/dl-runtime.h | 2 +- sysdeps/x86_64/dl-trampoline.h | 6 +-- 22 files changed, 155 insertions(+), 115 deletions(-) create mode 100644 sysdeps/generic/dl-fixup-attribute.h create mode 100644 sysdeps/i386/dl-fixup-attribute.h diff --git a/elf/dl-audit.c b/elf/dl-audit.c index 7d410bc128..c3569cb357 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #ifdef SHARED void @@ -335,3 +337,57 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, *value = DL_FIXUP_ADDR_VALUE (sym.st_value); } #endif + +#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \ + || ELF_MACHINE_NO_REL +# define PLTREL ElfW(Rela) +#else +# define PLTREL ElfW(Rel) +#endif + +void +DL_ARCH_FIXUP_ATTRIBUTE +_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg, + const void *inregs, void *outregs) +{ +#ifdef SHARED + const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]); + + /* This is the address in the array where we store the result of previous + relocations. */ + // XXX Maybe the bound information must be stored on the stack since + // XXX with bind_not a new value could have been stored in the meantime. + struct reloc_result *reloc_result = + &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))]; + ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, + l_info[DT_SYMTAB]) + + reloc_result->boundndx); + + /* Set up the sym parameter. */ + ElfW(Sym) sym = *defsym; + sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr); + + /* Get the symbol name. */ + const char *strtab = (const void *) D_PTR (reloc_result->bound, + l_info[DT_STRTAB]); + const char *symname = strtab + sym.st_name; + + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->ARCH_LA_PLTEXIT != NULL + && (reloc_result->enterexit + & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0) + { + struct auditstate *l_state = link_map_audit_state (l, cnt); + struct auditstate *bound_state + = link_map_audit_state (reloc_result->bound, cnt); + afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx, + &l_state->cookie, &bound_state->cookie, + inregs, outregs, symname); + } + + afct = afct->next; + } +#endif +} diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 4d16957c08..a0044b6776 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -16,8 +16,6 @@ License along with the GNU C Library; if not, see . */ -#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */ - #include #include #include @@ -37,12 +35,6 @@ # define PLTREL ElfW(Rel) #endif -/* The fixup functions might have need special attributes. If none - are provided define the macro as empty. */ -#ifndef ARCH_FIXUP_ATTRIBUTE -# define ARCH_FIXUP_ATTRIBUTE -#endif - /* This function is called through a special trampoline from the PLT the first time each PLT entry is called. We must perform the relocation @@ -52,7 +44,7 @@ function. */ DL_FIXUP_VALUE_TYPE -attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE +attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE _dl_fixup ( # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS ELF_MACHINE_RUNTIME_FIXUP_ARGS, @@ -179,7 +171,8 @@ _dl_fixup ( #ifndef PROF DL_FIXUP_VALUE_TYPE -__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE +__attribute ((noinline)) +DL_ARCH_FIXUP_ATTRIBUTE _dl_profile_fixup ( #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS ELF_MACHINE_RUNTIME_FIXUP_ARGS, @@ -363,52 +356,3 @@ _dl_profile_fixup ( } #endif /* PROF */ - - -#include -void -ARCH_FIXUP_ATTRIBUTE -_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg, - const void *inregs, void *outregs) -{ -#ifdef SHARED - const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]); - - /* This is the address in the array where we store the result of previous - relocations. */ - // XXX Maybe the bound information must be stored on the stack since - // XXX with bind_not a new value could have been stored in the meantime. - struct reloc_result *reloc_result = - &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))]; - ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, - l_info[DT_SYMTAB]) - + reloc_result->boundndx); - - /* Set up the sym parameter. */ - ElfW(Sym) sym = *defsym; - sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr); - - /* Get the symbol name. */ - const char *strtab = (const void *) D_PTR (reloc_result->bound, - l_info[DT_STRTAB]); - const char *symname = strtab + sym.st_name; - - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->ARCH_LA_PLTEXIT != NULL - && (reloc_result->enterexit - & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0) - { - struct auditstate *l_state = link_map_audit_state (l, cnt); - struct auditstate *bound_state - = link_map_audit_state (reloc_result->bound, cnt); - afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx, - &l_state->cookie, &bound_state->cookie, - inregs, outregs, symname); - } - - afct = afct->next; - } -#endif -} diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S index a7e9267c1c..9b352b1d0f 100644 --- a/sysdeps/aarch64/dl-trampoline.S +++ b/sysdeps/aarch64/dl-trampoline.S @@ -293,7 +293,7 @@ _dl_runtime_profile: ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0] add x2, x29, #OFFSET_RG add x3, x29, #OFFSET_RV - bl _dl_call_pltexit + bl _dl_audit_pltexit ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0] ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0] diff --git a/sysdeps/alpha/dl-trampoline.S b/sysdeps/alpha/dl-trampoline.S index 9dfce5b083..55380d48ad 100644 --- a/sysdeps/alpha/dl-trampoline.S +++ b/sysdeps/alpha/dl-trampoline.S @@ -187,7 +187,7 @@ _dl_runtime_profile_new: jsr $26, ($27), 0 ldgp $29, 0($26) - /* Set up for call to _dl_call_pltexit. */ + /* Set up for call to _dl_audit_pltexit. */ ldq $16, 16*8($15) ldq $17, 17*8($15) stq $0, 16*8($15) @@ -196,7 +196,7 @@ _dl_runtime_profile_new: lda $19, 16*8($15) stt $f0, 18*8($15) stt $f1, 19*8($15) - bsr $26, _dl_call_pltexit !samegp + bsr $26, _dl_audit_pltexit !samegp mov $15, $30 cfi_def_cfa_register (30) @@ -518,7 +518,7 @@ _dl_runtime_profile_old: jsr $26, ($27), 0 ldgp $29, 0($26) - /* Set up for call to _dl_call_pltexit. */ + /* Set up for call to _dl_audit_pltexit. */ ldq $16, 48*8($15) ldq $17, 49*8($15) stq $0, 46*8($15) @@ -527,7 +527,7 @@ _dl_runtime_profile_old: lda $19, 46*8($15) stt $f0, 48*8($15) stt $f1, 49*8($15) - bsr $26, _dl_call_pltexit !samegp + bsr $26, _dl_audit_pltexit !samegp mov $15, $30 cfi_def_cfa_register (30) diff --git a/sysdeps/arm/dl-trampoline.S b/sysdeps/arm/dl-trampoline.S index 70105308ca..a2d322706d 100644 --- a/sysdeps/arm/dl-trampoline.S +++ b/sysdeps/arm/dl-trampoline.S @@ -194,7 +194,7 @@ _dl_runtime_profile: ldmia ip, {r0,r1} add r2, r7, #72 add r3, r7, #0 - bl _dl_call_pltexit + bl _dl_audit_pltexit @ Return to caller. ldmia r7, {r0-r3} diff --git a/sysdeps/generic/dl-fixup-attribute.h b/sysdeps/generic/dl-fixup-attribute.h new file mode 100644 index 0000000000..aa92169b70 --- /dev/null +++ b/sysdeps/generic/dl-fixup-attribute.h @@ -0,0 +1,24 @@ +/* ABI specifics for lazy resolution functions. + 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 + . */ + +#ifndef _DL_FIXUP_ATTRIBUTE_H +#define _DL_FIXUP_ATTRIBUTE_H + +#define DL_ARCH_FIXUP_ATTRIBUTE + +#endif diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 32a621ae99..0958084268 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1387,6 +1388,14 @@ rtld_hidden_proto (_dl_audit_symbind_alt) void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize); +/* Call the la_pltexit() arch specific from audit modules for the link_map L. + The RELOC_ARGS is the relocation result value, INREGS is the arch-specific + input register state saved, and OUTREGS is the return value passed on the + callback. */ +void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l, + ElfW(Word) reloc_arg, + const void *inregs, + void *outregs); #endif /* SHARED */ #if PTHREAD_IN_LIBC && defined SHARED diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c index e7fbb7417d..b60a6b5390 100644 --- a/sysdeps/hppa/dl-runtime.c +++ b/sysdeps/hppa/dl-runtime.c @@ -26,7 +26,7 @@ _dl_fixup with the relocation offset. */ ElfW(Word) -attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE +attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE _dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l) { Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type; diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S index cb18ea7eab..c54879bae0 100644 --- a/sysdeps/hppa/dl-trampoline.S +++ b/sysdeps/hppa/dl-trampoline.S @@ -300,7 +300,7 @@ L(cont): ldw -4(%sp),%r1 copy %r1, %sp - /* Arguments to _dl_call_pltexit */ + /* Arguments to _dl_audit_pltexit */ ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */ ldw -120(%sp), %r25 /* (2) reloc offsets */ ldo -56(%sp), %r24 /* (3) *La_hppa_regs */ @@ -312,8 +312,8 @@ L(cont): ldo -128(%sp), %r1 fstd %fr4,0(%r1) - /* Call _dl_call_pltexit */ - bl _dl_call_pltexit,%rp + /* Call _dl_audit_pltexit */ + bl _dl_audit_pltexit,%rp nop /* Restore *La_hppa_retval */ diff --git a/sysdeps/i386/dl-fixup-attribute.h b/sysdeps/i386/dl-fixup-attribute.h new file mode 100644 index 0000000000..c10e9936f4 --- /dev/null +++ b/sysdeps/i386/dl-fixup-attribute.h @@ -0,0 +1,30 @@ +/* ABI specifics for lazy resolution functions. i386 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 + . */ + +#ifndef _DL_FIXUP_ATTRIBUTE_H +#define _DL_FIXUP_ATTRIBUTE_H + +/* We cannot use this scheme for profiling because the _mcount call destroys + the passed register information. */ +#ifndef PROF +# define DL_ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused)) +#else +# define DL_ARCH_FIXUP_ATTRIBUTE +#endif + +#endif diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 590b41d8d7..4751738731 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -118,29 +118,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) return lazy; } -#ifdef IN_DL_RUNTIME - -# ifndef PROF -/* We add a declaration of this function here so that in dl-runtime.c - the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters - in registers. - - We cannot use this scheme for profiling because the _mcount call - destroys the passed register information. */ -#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused)) - -extern ElfW(Addr) _dl_fixup (struct link_map *l, - ElfW(Word) reloc_offset) - ARCH_FIXUP_ATTRIBUTE; -extern ElfW(Addr) _dl_profile_fixup (struct link_map *l, - ElfW(Word) reloc_offset, - ElfW(Addr) retaddr, void *regs, - long int *framesizep) - ARCH_FIXUP_ATTRIBUTE; -# endif - -#endif - /* Mask identifying addresses reserved for the user program, where the dynamic linker should not map anything. */ #define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S index b5ec0326df..3a33051c52 100644 --- a/sysdeps/i386/dl-trampoline.S +++ b/sysdeps/i386/dl-trampoline.S @@ -265,7 +265,7 @@ _dl_runtime_profile: movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax # PLT1 movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx - call _dl_call_pltexit + call _dl_audit_pltexit movl LRV_EAX_OFFSET(%esp), %eax movl LRV_EDX_OFFSET(%esp), %edx fldt LRV_ST1_OFFSET(%esp) diff --git a/sysdeps/ia64/dl-trampoline.S b/sysdeps/ia64/dl-trampoline.S index 3053405a3a..11e86932c7 100644 --- a/sysdeps/ia64/dl-trampoline.S +++ b/sysdeps/ia64/dl-trampoline.S @@ -133,7 +133,7 @@ END(_dl_runtime_resolve) /* The fourth argument to _dl_profile_fixup and the third one to - _dl_call_pltexit are a pointer to La_ia64_regs: + _dl_audit_pltexit are a pointer to La_ia64_regs: 8byte r8 8byte r9 @@ -159,7 +159,7 @@ END(_dl_runtime_resolve) 8byte sp The fifth argument to _dl_profile_fixup is a pointer to long int. - The fourth argument to _dl_call_pltexit is a pointer to + The fourth argument to _dl_audit_pltexit is a pointer to La_ia64_retval: 8byte r8 @@ -261,7 +261,7 @@ ENTRY(_dl_runtime_profile) } { .mii mov r18 = ar.unat /* save it in La_ia64_regs */ - mov loc7 = out3 /* save it for _dl_call_pltexit */ + mov loc7 = out3 /* save it for _dl_audit_pltexit */ mov loc5 = r11 /* preserve language specific register */ } { .mmi @@ -272,7 +272,7 @@ ENTRY(_dl_runtime_profile) } { .mii mov ar.unat = r17 /* restore it for function call */ - mov loc8 = r16 /* save it for _dl_call_pltexit */ + mov loc8 = r16 /* save it for _dl_audit_pltexit */ nop.i 0x0 } { .mmi @@ -291,7 +291,7 @@ ENTRY(_dl_runtime_profile) { .mmi stf.spill [r2] = f14, 32 stf.spill [r3] = f15, 24 - mov loc9 = out1 /* save it for _dl_call_pltexit */ + mov loc9 = out1 /* save it for _dl_audit_pltexit */ ;; } { .mmb @@ -426,7 +426,7 @@ ENTRY(_dl_runtime_profile) br.call.sptk.many b0 = b6 } { .mii - /* Prepare stack for _dl_call_pltexit. Loc10 has the original + /* Prepare stack for _dl_audit_pltexit. Loc10 has the original stack pointer. */ adds r12 = -PLTEXIT_FRAME_SIZE, loc10 adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10 @@ -461,14 +461,14 @@ ENTRY(_dl_runtime_profile) { .mmi stf.spill [r2] = f12, 32 stf.spill [r3] = f13, 32 - /* We need to restore gp for _dl_call_pltexit. */ + /* We need to restore gp for _dl_audit_pltexit. */ mov gp = loc11 ;; } { .mmb stf.spill [r2] = f14 stf.spill [r3] = f15 - br.call.sptk.many b0 = _dl_call_pltexit + br.call.sptk.many b0 = _dl_audit_pltexit } { .mmi /* Load all the non-floating and floating return values. Skip diff --git a/sysdeps/m68k/dl-trampoline.S b/sysdeps/m68k/dl-trampoline.S index a51a5f7f57..72bde664c3 100644 --- a/sysdeps/m68k/dl-trampoline.S +++ b/sysdeps/m68k/dl-trampoline.S @@ -202,7 +202,7 @@ _dl_runtime_profile: cfi_adjust_cfa_offset (4) move.l (32+FPSPACE)(%sp), -(%sp) cfi_adjust_cfa_offset (4) - jbsr _dl_call_pltexit + jbsr _dl_audit_pltexit lea 16(%sp), %sp cfi_adjust_cfa_offset (-16) move.l (%sp)+, %d0 diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S index 61bd8571fc..97f0105ce7 100644 --- a/sysdeps/powerpc/powerpc64/dl-trampoline.S +++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S @@ -197,7 +197,7 @@ END(_dl_runtime_resolve) #ifndef PROF ENTRY (_dl_profile_resolve, 4) /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we - need to call _dl_call_pltexit. */ + need to call _dl_audit_pltexit. */ std r31,-8(r1) std r30,-16(r1) /* We need to save the registers used to pass parameters, ie. r3 thru @@ -452,7 +452,7 @@ L(restoreFXR2): L(callpltexit): addi r5,r1,INT_PARMS addi r6,r1,INT_RTN - bl JUMPTARGET(_dl_call_pltexit) + bl JUMPTARGET(_dl_audit_pltexit) #ifndef SHARED nop #endif diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h index c224a2b928..9e4cd1055f 100644 --- a/sysdeps/s390/s390-32/dl-trampoline.h +++ b/sysdeps/s390/s390-32/dl-trampoline.h @@ -282,7 +282,7 @@ _dl_runtime_profile: basr %r1,0 5: l %r14,7f-5b(%r1) la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_32_retval * - bas %r14,0(%r14,%r1) # call _dl_call_pltexit + bas %r14,0(%r14,%r1) # call _dl_audit_pltexit lr %r15,%r12 # remove stack frame # undef FRAME_SIZE @@ -301,7 +301,7 @@ _dl_runtime_profile: br %r14 6: .long _dl_profile_fixup - 0b -7: .long _dl_call_pltexit - 5b +7: .long _dl_audit_pltexit - 5b cfi_endproc .size _dl_runtime_profile, .-_dl_runtime_profile # undef SIZEOF_STRUCT_LA_S390_32_REGS diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h index ae741a3bad..6e5bad4045 100644 --- a/sysdeps/s390/s390-64/dl-trampoline.h +++ b/sysdeps/s390/s390-64/dl-trampoline.h @@ -284,7 +284,7 @@ _dl_runtime_profile: lmg %r2,%r4,CFA_OFF+PLT1_OFF(%r12) # r2, r3: args saved by PLT # r4: struct La_s390_64_regs * la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_64_retval * - brasl %r14,_dl_call_pltexit + brasl %r14,_dl_audit_pltexit lgr %r15,%r12 # remove stack frame # undef FRAME_SIZE diff --git a/sysdeps/sh/dl-trampoline.S b/sysdeps/sh/dl-trampoline.S index 824ac84ba1..f9038cd10e 100644 --- a/sysdeps/sh/dl-trampoline.S +++ b/sysdeps/sh/dl-trampoline.S @@ -423,8 +423,8 @@ _dl_runtime_profile: .align 2 #ifdef SHARED 7: .long _GLOBAL_OFFSET_TABLE_ -8: .long _dl_call_pltexit@GOTOFF +8: .long _dl_audit_pltexit@GOTOFF #else -8: .long _dl_call_pltexit +8: .long _dl_audit_pltexit #endif .size _dl_runtime_profile, .-_dl_runtime_profile diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S index 426f90c99a..2f64809731 100644 --- a/sysdeps/sparc/sparc32/dl-trampoline.S +++ b/sysdeps/sparc/sparc32/dl-trampoline.S @@ -127,7 +127,7 @@ _dl_profile_invoke: mov %l5, %o0 mov %l6, %o1 add %sp, (11 * 8), %o2 - call _dl_call_pltexit + call _dl_audit_pltexit add %sp, ( 9 * 8), %o3 ldd [%sp + ( 9 * 8)], %i0 diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S index 8d59fa6720..86605e37ac 100644 --- a/sysdeps/sparc/sparc64/dl-trampoline.S +++ b/sysdeps/sparc/sparc64/dl-trampoline.S @@ -196,7 +196,7 @@ _dl_profile_invoke: mov %l5, %o0 mov %l6, %o1 add %sp, STACK_BIAS + (24 * 8), %o2 - call _dl_call_pltexit + call _dl_audit_pltexit add %sp, STACK_BIAS + (16 * 8), %o3 ldx [%sp + STACK_BIAS + (16 * 8)], %i0 diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h index 9c8d3977ee..19ba33ef30 100644 --- a/sysdeps/x86_64/dl-runtime.h +++ b/sysdeps/x86_64/dl-runtime.h @@ -18,7 +18,7 @@ 02111-1307 USA. */ /* The ABI calls for the PLT stubs to pass the index of the relocation - and not its offset. In _dl_profile_fixup and _dl_call_pltexit we + and not its offset. In _dl_profile_fixup and _dl_audit_pltexit we also use the index. Therefore it is wasteful to compute the offset in the trampoline just to reverse the operation immediately afterwards. */ diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h index b9a12970cd..b5de7efff7 100644 --- a/sysdeps/x86_64/dl-trampoline.h +++ b/sysdeps/x86_64/dl-trampoline.h @@ -388,7 +388,7 @@ _dl_runtime_profile: jns 3f /* There's nothing in the frame size, so there - will be no call to the _dl_call_pltexit. */ + will be no call to the _dl_audit_pltexit. */ /* Get back registers content. */ movq LR_RCX_OFFSET(%rsp), %rcx @@ -436,7 +436,7 @@ _dl_runtime_profile: mov 24(%rbx), %RSP_LP # Drop the copied stack content /* Now we have to prepare the La_x86_64_retval structure for the - _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now, + _dl_audit_pltexit. The La_x86_64_regs is being pointed by rsp now, so we just need to allocate the sizeof(La_x86_64_retval) space on the stack, since the alignment has already been taken care of. */ # ifdef RESTORE_AVX @@ -491,7 +491,7 @@ _dl_runtime_profile: movq 24(%rbx), %rdx # La_x86_64_regs argument to %rdx. movq 40(%rbx), %rsi # Copy args pushed by PLT in register. movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index - call _dl_call_pltexit + call _dl_audit_pltexit /* Restore return registers. */ movq LRV_RAX_OFFSET(%rsp), %rax From patchwork Fri Jul 30 19:47:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44532 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 712B83983C4D for ; Fri, 30 Jul 2021 19:58:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 712B83983C4D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675133; bh=u1wIjbM33qZYb73+q1rReeW7z3zmrQxb1bisEVePjpw=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=CkfsY/EZEREdTAhvd05jv4/lBTaC1QYDhPKaX6Jf994x2M3/F3yxcLc8r41RwQnPV fmWQxPppFYrS+aNNuHYuBOlaUaIIXDLoDAxHZ6BE8o35R0irp8TzBLv9KJTqDnkeu+ cMI5LT8AP64/XdNHt6pWzCRyf65PmWqs/Mzx8sg0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id 19B42398202E for ; Fri, 30 Jul 2021 19:47:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 19B42398202E Received: by mail-pl1-x62e.google.com with SMTP id c16so12313070plh.7 for ; Fri, 30 Jul 2021 12:47:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=u1wIjbM33qZYb73+q1rReeW7z3zmrQxb1bisEVePjpw=; b=I2iRCtzV8llfM6h1s4z8nshbnVSLSaNt9NzckxYvNTBKqwk7aZHG8gmJvFkxa8Tkv2 FCQP44OPt75qtiJgbuXpIojTOtG9Fu8ERQgHnZTK9qKtIuzYWM+PH3XkuYyXqzW7V2YD Ssa11DzdSPuJQYbkBqT7db7K3sRWwh6NhcsaJmOLRIvwMGNc8xazmHrm3+gxXaPwohAp t4BJb7HpO+CWBpAIdevSIMz1co65kN0lOcoShGWc6q2xqRF9xofpzlp1ybCusGXT6D2W Im2Y3FHpcsrsn2MNAuBOIdtV75vGFzP7p0kbG9bWSmxv9qoCoJGazJgieUEhOt/weYZZ 19XQ== X-Gm-Message-State: AOAM532dzpq7tIjKm7r9B/4hIUOH0DlS843/Fgb2XRkGqwEeCAr7i5qQ wQeM0p/zvzGUN9CpkiJJafyx/ZyKRieS3Q== X-Google-Smtp-Source: ABdhPJwBPPYvlUgOXLvq/9FnPkGiuywLkRtKfEup+mnIKWxYkGZToyuF6NgDnc34qCAi43nO3ncMkg== X-Received: by 2002:a63:1926:: with SMTP id z38mr2684442pgl.451.1627674469906; Fri, 30 Jul 2021 12:47:49 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:49 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 14/20] elf: Issue audit la_objopen() for vDSO Date: Fri, 30 Jul 2021 16:47:09 -0300 Message-Id: <20210730194715.881900-15-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The vDSO is is listed in the link_map chain, but is never the subject of an la_objopen call. A new internal flag __RTLD_VDSO is added that acts as __RTLD_OPENEXEC to allocate the required 'struct auditstate' extra space for the 'struct link_map'. The return value from the callback() is currently ignored, since there is no PLT call involved by glibc when using the vDSO, neither the vDSO are exported directly. Checked on x86_64-linux-gnu. --- 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(-) create mode 100644 elf/tst-audit22.c create mode 100644 elf/tst-auditmod22.c diff --git a/elf/Makefile b/elf/Makefile index c6c97efd8c..11f87ba46a 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 \ @@ -310,6 +311,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 \ @@ -1526,6 +1528,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 1cbaaa2124..04bcab3670 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1884,6 +1884,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 From patchwork Fri Jul 30 19:47:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44533 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8DE633984053 for ; Fri, 30 Jul 2021 19:59:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8DE633984053 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675184; bh=vjgo0tTFLUM3V1goemoXihHHI40uYePgxzAsDcw7LTM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Cl3v06XyLcsSlzy5jhBd5x7FwL7TB0cyzwquOownXO8RLfndC/WRCW89c5Hg7Q2s0 H3YZMA1vTtvf9p8Xr96RDuCe6mev0soSQVJA9UIhvDK2oo8dKTUxw9cuPlwyeat2XM Zw6eHTdKdIUAFHdK0qwO+7ckpAYjMe27TjZcsQq8= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id B83683848437 for ; Fri, 30 Jul 2021 19:47:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B83683848437 Received: by mail-pj1-x102c.google.com with SMTP id q17-20020a17090a2e11b02901757deaf2c8so16073725pjd.0 for ; Fri, 30 Jul 2021 12:47:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vjgo0tTFLUM3V1goemoXihHHI40uYePgxzAsDcw7LTM=; b=a6cA2cMG8UWZOGGszFBPBm9gdEIcl8sPdltwRm5/dSoCxh8wDb8KSriglGtJ2lNJvt h+yKiOiNzlzdF9TSE1BY9kOevDaV5bKgYgo06UXDe1bMp2DpegSa+Q0IQL/aGui1trnm Dq9pEMi8owGaWQXNrctdBPi627Yq2da//aaU+e49FqdkPba2VCZwnudpRzwd34+0+OXX PygBp8xE8s0FiTxu75CYLFJ0PXBZPLCqRptUIp8bFvCDhBEJuEkqmqJbao/lOVFZ3jdX tdKBE45J1urpqAQg/ozrQOoOQRmx8Q+m/H7rRlqFYQlWEPJ63vFf2U4qVE/hltRyhQao D3Iw== X-Gm-Message-State: AOAM530KH2gvy4ZAGp/1BuQxWhOUlJxhuDANJYnCVWNuRxCj9TNpmZ4T fxzNUoSUmf1DwheWyxMKJ2Tt1dTJyavoGQ== X-Google-Smtp-Source: ABdhPJz6HN2gf6VK/euLp39hdsuQkmU+sDtHKyyKMNZhvxkapgzATMxVmp76cB0dl6zxvw97wXr5dA== X-Received: by 2002:a05:6a00:2c6:b029:3a9:ca04:7993 with SMTP id b6-20020a056a0002c6b02903a9ca047993mr4593591pft.19.1627674471577; Fri, 30 Jul 2021 12:47:51 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:51 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 15/20] elf: Add main application on main_map l_name Date: Fri, 30 Jul 2021 16:47:10 -0300 Message-Id: <20210730194715.881900-16-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" For the la_objopen() the path listed in link_map->l_name for the main application binary is empty, even though dladdr() is able to recover the correct path. By setting the expected application name on l_name, it allows to simplify the code to handle the special case and make the API that return such information (la_objopen(), dladdr() and dlinfo() to have similar semantic. Checked on x86_64-linux-gnu. --- dlfcn/Makefile | 4 ++- dlfcn/tst-dladdr-self.c | 55 +++++++++++++++++++++++++++++++++++++++++ elf/dl-addr.c | 5 ---- elf/dl-dst.h | 2 +- elf/dl-init.c | 3 +-- elf/dl-load.c | 9 +++++-- elf/dl-misc.c | 1 + elf/rtld.c | 6 +---- elf/tst-audit22.c | 4 +++ elf/tst-auditmod22.c | 8 ++++++ gmon/gmon.c | 10 ++++---- 11 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 dlfcn/tst-dladdr-self.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 6bbfbb8344..bceb2b2885 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -51,7 +51,7 @@ endif ifeq (yes,$(build-shared)) tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ - bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen + bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-dladdr-self endif modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ defaultmod2 errmsg1mod modatexit modcxaatexit \ @@ -143,3 +143,5 @@ $(objpfx)bug-dl-leaf.out: $(objpfx)bug-dl-leaf-lib-cb.so $(objpfx)bug-dl-leaf-lib-cb.so: $(objpfx)bug-dl-leaf-lib.so $(objpfx)tst-rec-dlopen.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so + +LDFLAGS-tst-dladdr-self = -rdynamic diff --git a/dlfcn/tst-dladdr-self.c b/dlfcn/tst-dladdr-self.c new file mode 100644 index 0000000000..0eddaf1cd7 --- /dev/null +++ b/dlfcn/tst-dladdr-self.c @@ -0,0 +1,55 @@ +/* Check dladdr with the reference to own exectuable. + 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 + +void +test_symbol (void) +{ +} + +static int +do_test (void) +{ + void *handle = xdlopen (NULL, RTLD_NOW); + int (*sym)(void) = xdlsym (handle, "test_symbol"); + + Dl_info info = { 0 }; + { + int r = dladdr (sym, &info); + TEST_VERIFY_EXIT (r != 0); + } + + { + const char *p = strrchr (info.dli_fname, '/'); + const char *dli_name = p == NULL ? info.dli_fname : p + 1; + + TEST_COMPARE_STRING (dli_name, "tst-dladdr-self"); + } + + TEST_COMPARE_STRING (info.dli_sname, "test_symbol"); + TEST_COMPARE ((uintptr_t) info.dli_saddr, (uintptr_t) test_symbol); + + return 0; +} + +#include diff --git a/elf/dl-addr.c b/elf/dl-addr.c index 3226880d48..c2c93c63ad 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -30,11 +30,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, info->dli_fname = match->l_name; info->dli_fbase = (void *) match->l_map_start; - /* If this is the main program the information is incomplete. */ - if (__builtin_expect (match->l_name[0], 'a') == '\0' - && match->l_type == lt_executable) - info->dli_fname = _dl_argv[0]; - const ElfW(Sym) *symtab = (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]); const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]); diff --git a/elf/dl-dst.h b/elf/dl-dst.h index 34bbaf65dc..a1e9af5a06 100644 --- a/elf/dl-dst.h +++ b/elf/dl-dst.h @@ -44,7 +44,7 @@ auditing, in ld.so. */ \ if ((l)->l_origin == NULL) \ { \ - assert ((l)->l_name[0] == '\0' || IS_RTLD (l)); \ + assert ((l)->l_type == lt_executable || IS_RTLD (l)); \ (l)->l_origin = _dl_get_origin (); \ dst_len = ((l)->l_origin && (l)->l_origin != (char *) -1 \ ? strlen ((l)->l_origin) : 0); \ diff --git a/elf/dl-init.c b/elf/dl-init.c index f924d26642..9fa8403290 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -39,8 +39,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env) l->l_init_called = 1; /* Check for object which constructors we do not run here. */ - if (__builtin_expect (l->l_name[0], 'a') == '\0' - && l->l_type == lt_executable) + if (l->l_type == lt_executable) return; /* Print a debug message if wanted. */ diff --git a/elf/dl-load.c b/elf/dl-load.c index 8f8971de29..de04332cf3 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1990,13 +1990,18 @@ _dl_map_object (struct link_map *loader, const char *name, assert (nsid >= 0); assert (nsid < GL(dl_nns)); + /* Special case: trying to map itself. */ + if (name[0] == '\0') + return GL(dl_ns)[nsid]._ns_loaded; + /* Look for this name among those already loaded. */ for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next) { /* If the requested name matches the soname of a loaded object, use that object. Elide this check for names that have not - yet been opened. */ - if (__glibc_unlikely ((l->l_faked | l->l_removed) != 0)) + yet been opened or the executable itself. */ + if (__glibc_unlikely ((l->l_faked | l->l_removed + || l->l_type == lt_executable) != 0)) continue; if (!_dl_name_match_p (name, l)) { diff --git a/elf/dl-misc.c b/elf/dl-misc.c index b256d792c6..b62bbcb8b4 100644 --- a/elf/dl-misc.c +++ b/elf/dl-misc.c @@ -338,6 +338,7 @@ rtld_hidden_def (_dl_fatal_printf) int _dl_name_match_p (const char *name, const struct link_map *map) { + /* Filter out the main executable. */ if (strcmp (name, map->l_name) == 0) return 1; diff --git a/elf/rtld.c b/elf/rtld.c index 04bcab3670..63248c86d0 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1359,11 +1359,6 @@ dl_main (const ElfW(Phdr) *phdr, phdr = main_map->l_phdr; phnum = main_map->l_phnum; - /* We overwrite here a pointer to a malloc()ed string. But since - the malloc() implementation used at this point is the dummy - implementations which has no real free() function it does not - makes sense to free the old string first. */ - main_map->l_name = (char *) ""; *user_entry = main_map->l_entry; #ifdef HAVE_AUX_VECTOR @@ -1426,6 +1421,7 @@ dl_main (const ElfW(Phdr) *phdr, information for the program. */ } + main_map->l_name = _dl_argv[0]; main_map->l_map_end = 0; main_map->l_text_end = 0; /* Perhaps the executable has no PT_LOAD header entries at all. */ diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c index c1b301c4cc..7718e3e959 100644 --- a/elf/tst-audit22.c +++ b/elf/tst-audit22.c @@ -94,6 +94,7 @@ do_test (int argc, char *argv[]) unsigned long vdso_process = 0; unsigned long vdso_audit = 0; + bool mainapp_found = false; FILE *out = fmemopen (result.err.buffer, result.err.length, "r"); TEST_VERIFY (out != NULL); @@ -105,9 +106,12 @@ do_test (int argc, char *argv[]) vdso_process = parse_address (buffer + strlen ("vdso: ")); else if (startswith (buffer, "vdso found: ")) vdso_audit = parse_address (buffer + strlen ("vdso found: ")); + else if (startswith (buffer, "mainapp found")) + mainapp_found = true; } TEST_COMPARE (vdso_process, vdso_audit); + TEST_COMPARE (mainapp_found, true); free (buffer); xfclose (out); diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c index 02275bed57..a4921f35de 100644 --- a/elf/tst-auditmod22.c +++ b/elf/tst-auditmod22.c @@ -19,6 +19,7 @@ #include #include #include +#include #include unsigned int @@ -30,6 +31,13 @@ la_version (unsigned int version) 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 ? map->l_name : p + 1; + if (strcmp (l_name, "tst-audit22") == 0) + fprintf (stderr, "mainapp found\n"); + } + if (map->l_addr == getauxval (AT_SYSINFO_EHDR)) fprintf (stderr, "vdso found: %" PRIxPTR "\n", (uintptr_t) map->l_addr); diff --git a/gmon/gmon.c b/gmon/gmon.c index dee64803ad..cb8327b8e4 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -48,16 +48,16 @@ #ifdef PIC # include +# include static int callback (struct dl_phdr_info *info, size_t size, void *data) { - if (info->dlpi_name[0] == '\0') + if (info->dlpi_name == _dl_argv[0]) { - /* The link map for the executable is created by calling - _dl_new_object with "" as filename. dl_iterate_phdr - calls the callback function with filename from the - link map as dlpi_name. */ + /* The link map l_name for the executable is set to the _dl_argv[0] + after argument processing. dl_iterate_phdr() calls the callback + function with filename from the link map as dlpi_name. */ u_long *load_address = data; *load_address = (u_long) info->dlpi_addr; return 1; From patchwork Fri Jul 30 19:47:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44534 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 997983983C76 for ; Fri, 30 Jul 2021 20:00:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 997983983C76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675229; bh=HxLU2b/JBkT1vZcwH/Az8YMM1/7yL6rQszXY0+vSPpM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=trkE9GdS0uJR5sOOcAcy0GFIdL+eBlnDUazNGqCl4mv8rtjubDjrBCuq8ISGIFQrW Hg/2+Ipo3xLd05VPYk6hbrjltiJgFp8EWBUSNSQROUEyvHXEXM/mw68A4OxX28rz0m 36YL7woFB3iKyqBPuYLceOf8FPw3SqCba/oDwn8g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id 5BFF7397EC05 for ; Fri, 30 Jul 2021 19:47:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5BFF7397EC05 Received: by mail-pj1-x102c.google.com with SMTP id mz5-20020a17090b3785b0290176ecf64922so22301341pjb.3 for ; Fri, 30 Jul 2021 12:47:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HxLU2b/JBkT1vZcwH/Az8YMM1/7yL6rQszXY0+vSPpM=; b=TeKbUB7+C0Av/BbwokeGPeCrhvPTR8wtqqlk79JCgJc8BbMPwRXNxFfQWUvBgqeuq4 2q3gFvPZs1Erpb/ll7qHOXb3TEBfh8vj5XgGF1iCp8x99vRESgXQegnnFS01Q11mu8C0 GypDmQIDzeL4mkaW6NQYiDfQjSatK/rqyOzw8EJ2Ky6SPsHSfnusBjgN8neHiSyDm3Ny 7UNrsUaHJQisM+8D0auRov/nJWC9bSs5an3aM+u/AIVm19eJLPnVaX0SEtyvTjNzoqdi cj5QSY1SW/f8J1yT9zO9mVZTGVCLsw2UCqVgmNnFx0B7gyR2DMoCqOx1g/UUMbtgr6ko dh+A== X-Gm-Message-State: AOAM531PbYVhwMgMhv9UKenY2y9sI66sRi9R/MsP5m1aniOf3L26+UWf Q+6HMPVOC0+OlEgKGBI2yp/eivyEMhPRBA== X-Google-Smtp-Source: ABdhPJw9arYiX9eybvsdVeIQlMr9pzJyfQr/Cge++jPneKFrdwXMs9gtu7hJGA+cZ/421RiaZW49FQ== X-Received: by 2002:a05:6a00:2171:b029:3ab:eca3:af59 with SMTP id r17-20020a056a002171b02903abeca3af59mr4168643pff.46.1627674473193; Fri, 30 Jul 2021 12:47:53 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:52 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 16/20] elf: Add la_activity during application exit Date: Fri, 30 Jul 2021 16:47:11 -0300 Message-Id: <20210730194715.881900-17-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" la_activity() is not called during application exit, even though la_objclose is. Checked on x86_64-linux-gnu. --- elf/Makefile | 6 ++ elf/dl-fini.c | 9 +++ elf/tst-audit23.c | 161 +++++++++++++++++++++++++++++++++++++++++++ elf/tst-audit23mod.c | 23 +++++++ elf/tst-auditmod23.c | 78 +++++++++++++++++++++ 5 files changed, 277 insertions(+) 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 11f87ba46a..bbe59176b2 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -226,6 +226,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit20 \ tst-audit21 \ tst-audit22 \ + tst-audit23 \ 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 \ @@ -312,6 +313,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod20 tst-audit20mod \ tst-auditmod21 \ tst-auditmod22 \ + tst-auditmod23 tst-audit23mod \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1531,6 +1533,10 @@ tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21.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 35a5471dcd..5e12525c7c 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -64,6 +64,10 @@ _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]; @@ -154,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..41bb4cb367 --- /dev/null +++ b/elf/tst-audit23.c @@ -0,0 +1,161 @@ +/* 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 ? 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 (); + + 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); + + + /* We expect la_objopen/la_objclose for the objects: + 1. executable + 2. loader + 3. libc.so + 4. tst-audit23mod.so + 5. libc.so (LM_ID_NEWLM) */ + enum { max_objs = 5 }; + 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; + + 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)) + { + enum { LA_OBJOPEN, LA_OBJCLOSE} mode; + ptrdiff_t offset; + if (startswith (buffer, "la_objopen: ")) + { + offset = strlen ("la_objopen: "); + mode = LA_OBJOPEN; + } + else if (startswith (buffer, "la_objclose: ")) + { + offset = strlen ("la_objclose: "); + mode = LA_OBJCLOSE; + } + else + continue; + + char *lname; + uintptr_t laddr; + Lmid_t lmid; + int r = sscanf (buffer + offset, "%ms %"SCNxPTR" %ld", &lname, &laddr, + &lmid); + TEST_COMPARE (r, 3); + + if (mode == LA_OBJOPEN) + { + 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++; + } + else if (mode == LA_OBJCLOSE) + { + 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; + } + } + } + } + + for (size_t i = 0; i < nobjs; i++) + { + TEST_COMPARE (objs[i].closed, true); + free (objs[i].lname); + } + + free (buffer); + xfclose (out); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include 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 + . */ + +int +foo (void) +{ + return 0; +} diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c new file mode 100644 index 0000000000..20ef19945d --- /dev/null +++ b/elf/tst-auditmod23.c @@ -0,0 +1,78 @@ +/* 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 + . */ + +#include +#include +#include +#include +#include +#include + +static uintptr_t vdso_addr; + +unsigned int +la_version (unsigned int version) +{ + vdso_addr = getauxval (AT_SYSINFO_EHDR); + /* The main_map for the executable returns 0 for l_addr. */ + if (vdso_addr == 0) + vdso_addr = -1; + return LAV_CURRENT; +} + +struct map_desc_t +{ + char *lname; + uintptr_t laddr; + Lmid_t lmid; +}; + + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + if (map->l_addr == vdso_addr) + return 0; + + fprintf (stderr, "%s: %s %"PRIxPTR" %ld\n", __func__, + map->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 (map->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: %s %"PRIxPTR" %ld\n", __func__, + map_desc->lname, map_desc->laddr, map_desc->lmid); + free (map_desc->lname); + free (map_desc); + + return 0; +} From patchwork Fri Jul 30 19:47:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44535 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E586A398502E for ; Fri, 30 Jul 2021 20:01:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E586A398502E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675274; bh=7kwaRaCkvzKK3Kgg8m9adjbzhonXOWofN2inf+TJpDg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Fb1GeponECsb7GTlh8mOU+56kGJyuYFZfa6aFCQbA7n3DZ9Nm3qU49Jg3cQJoLeO3 G4dCKMqu2P9w4Kv5KfH7+Y26CfZ+0yCMYIpqu1g5BFII+2th7rIcoD9K8VGEvJdcfy 3n1nrj4BLAy0NSWj37MGGOhR+BDYZlbE6C+2ez5c= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by sourceware.org (Postfix) with ESMTPS id A017A384F00D for ; Fri, 30 Jul 2021 19:47:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A017A384F00D Received: by mail-pj1-x1036.google.com with SMTP id a4-20020a17090aa504b0290176a0d2b67aso22343939pjq.2 for ; Fri, 30 Jul 2021 12:47:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7kwaRaCkvzKK3Kgg8m9adjbzhonXOWofN2inf+TJpDg=; b=NznvBxj9AXONmf6XVc6renTFOCmspzQHuHsGgTjz4M30Zd25synhknJxGff/qo546o TF6GsNSMWsIx7w2p9Ns56G+ABSX44OYBg/E7q/ftq6VlUfZOAhpRtEDQREQTf4x3qGOO ho0rQ1r4Av9RUb8fKrib9U5wNVCkGgvP2CBSWmh5dh6LCiFrKjPd7qpwbBjaIJXOhBd8 t/eXOX8MknUrxFRtgFSZGmXC+fbs3fe57KGOMZlFliX5s0X1OjhHoJMOozTkn7jgMlbd J8nehE165f1hgXDU5VSQ/rlybcyXfHv9S7dUT2yWYJUD1oYuaR6XmCB0CnzeAyWw1Rcj tOQw== X-Gm-Message-State: AOAM532uKhpC7LFsRTmhbf8fhG0a/rVN1xA2/Qn6zA07flt8mLk1bD51 LtY7C38lMpjSTGKXixwSVPXGYmpqDEl4zw== X-Google-Smtp-Source: ABdhPJyya8mhvDFItm/k8WkEfv/6ViNVeFrXzuNfwyH6S7q071896eviI3CCKUiI58Pj75YYEco2Og== X-Received: by 2002:a17:90a:3489:: with SMTP id p9mr4894504pjb.197.1627674474868; Fri, 30 Jul 2021 12:47:54 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:54 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 17/20] elf: Issue la_symbind() for bind-now (BZ #23734) Date: Fri, 30 Jul 2021 16:47:12 -0300 Message-Id: <20210730194715.881900-18-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The audit callback is not called for binaries built with -Wl,-z,now or when LD_BIND_NOW=1 is used. The PLT tracking callbacks are still not issue for such case, since this will would change the expected program semantic (where no PTL is expected) and also yield performance implications (such as for BZ#15533). Checked on x86_64-linux-gnu and aarch64-linux-gnu. --- elf/Makefile | 50 ++++++++++++++++++ elf/dl-reloc.c | 8 ++- elf/do-rel.h | 62 +++++++++++++++++----- 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-auditmod22.c | 22 +++++++- elf/tst-auditmod24a.c | 104 +++++++++++++++++++++++++++++++++++++ elf/tst-auditmod24b.c | 99 +++++++++++++++++++++++++++++++++++ elf/tst-auditmod24c.c | 3 ++ elf/tst-auditmod24d.c | 114 +++++++++++++++++++++++++++++++++++++++++ 20 files changed, 780 insertions(+), 20 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-auditmod24a.c create mode 100644 elf/tst-auditmod24b.c create mode 100644 elf/tst-auditmod24c.c create mode 100644 elf/tst-auditmod24d.c diff --git a/elf/Makefile b/elf/Makefile index bbe59176b2..bfed7043a5 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -227,6 +227,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit21 \ tst-audit22 \ tst-audit23 \ + tst-audit24a tst-audit24b tst-audit24c tst-audit24d \ 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 \ @@ -314,6 +315,11 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod21 \ 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 \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1537,6 +1543,50 @@ $(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 + # 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-reloc.c b/elf/dl-reloc.c index c6bc1e6b4e..fb47b5939f 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -206,9 +206,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], /* If DT_BIND_NOW is set relocate all references in this object. We do not do this if we are profiling, of course. */ - // XXX Correct for auditing? - if (!consider_profiling - && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) + if (!consider_profiling && l->l_info[DT_BIND_NOW] != NULL) lazy = 0; if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) @@ -286,8 +284,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], #include "dynamic-link.h" - ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); - #ifndef PROF if (consider_profiling | consider_symbind && l->l_info[DT_PLTRELSZ] != NULL) @@ -310,6 +306,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], } } #endif + + ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); } /* Mark the object so we know this work has been done. */ diff --git a/elf/do-rel.h b/elf/do-rel.h index 321ac2b359..455e6a8b2e 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 . */ +#include + /* This file may be included twice, to define both `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ @@ -121,8 +123,15 @@ elf_dynamic_do_Rel (struct link_map *map, const ElfW(Half) *const version = (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); +#if defined SHARED && !defined RTLD_BOOTSTRAP + size_t ri = 0; +#endif 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) { @@ -132,11 +141,18 @@ elf_dynamic_do_Rel (struct link_map *map, continue; } #endif - - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], - &map->l_versions[ndx], - (void *) (l_addr + r->r_offset), skip_ifunc); + elf_machine_rel (map, 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 + && l->l_reloc_result != NULL) + { + struct link_map *sym_map + = RESOLVE_MAP (&sym, rversion, ELF_MACHINE_JMP_SLOT); + if (sym != NULL) + _dl_audit_symbind (map, &map->l_reloc_result[ri++], sym, + r_addr_arg, sym_map); + } +#endif } #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP @@ -157,18 +173,36 @@ elf_dynamic_do_Rel (struct link_map *map, #ifndef RTLD_BOOTSTRAP else { +# if defined SHARED && !defined RTLD_BOOTSTRAP + size_t ri = 0; +# endif 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, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, - (void *) (l_addr + r->r_offset), skip_ifunc); + elf_machine_rel (map, 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 + && l->l_reloc_result != NULL) + { + struct link_map *sym_map + = RESOLVE_MAP (&sym, (struct r_found_version *) NULL, + ELF_MACHINE_JMP_SLOT); + if (sym != NULL) + _dl_audit_symbind (map, &map->l_reloc_result[ri++], sym, + r_addr_arg, sym_map); + } +# endif + } # ifdef ELF_MACHINE_IRELATIVE if (r2 != NULL) diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c new file mode 100644 index 0000000000..24160f4685 --- /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 + . */ + +#include +#include + +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 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 + . */ + +#include + +_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 + . */ + +#include + +_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..44643d64ef --- /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 + . */ + +/* This is similar to tst-audit24a, with the difference this modules + does not have the .gnu.version section header. */ + +#include +#include + +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 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 + . */ + +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 + . */ + +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..79b580331a --- /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 + . */ + +#include +#include + +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 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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include + +_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 + . */ + +#include + +_Noreturn int +tst_audit24dmod4_func1 (void) +{ + abort (); +} diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c index a4921f35de..9b17039a5d 100644 --- a/elf/tst-auditmod22.c +++ b/elf/tst-auditmod22.c @@ -41,5 +41,25 @@ 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; + return 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) +{ + fprintf (stderr, "%s: %s\n", __func__, symname); + return sym->st_value; +} +#else +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +{ + fprintf (stderr, "%s: %s\n", __func__, symname); + return sym->st_value; +} +#endif diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c new file mode 100644 index 0000000000..4b5cc2ec5e --- /dev/null +++ b/elf/tst-auditmod24a.c @@ -0,0 +1,104 @@ +/* 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 + . */ + +#include +#include +#include +#include + +#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 ? map->l_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) + { + 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)) + 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..33129104c5 --- /dev/null +++ b/elf/tst-auditmod24b.c @@ -0,0 +1,99 @@ +/* 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 + . */ + +#include +#include +#include +#include + +#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 ? map->l_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)) + 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..3ed4c772a2 --- /dev/null +++ b/elf/tst-auditmod24d.c @@ -0,0 +1,114 @@ +/* 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 + . */ + +#include +#include +#include +#include +#include + + +#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 ? map->l_name : 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; +} + +#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) + return (uintptr_t) tst_audit24dmod3_func1; + } + + abort (); +} From patchwork Fri Jul 30 19:47:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44537 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1CF75398641F for ; Fri, 30 Jul 2021 20:02:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1CF75398641F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675374; bh=ZKwRX28Sj413YBlfQ2sbg6erFk0t3sb+0miIuzYHMpg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=eXuYRfg79sx/bvIf/uyefTUQBsaqXRTiv9pRK4PMQWi/S9tEFnCdQFiOkoPKv9w9P OZnd8xcC6DmnSeqCrSRvCa4G1G9jzf0UKVPDjWjShw3ppI7F+X/o4kEgbtcNZAB0bJ iN2UDGscnhfTWWf8zOXpFsfLOibMUWlpabK9evUI= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id 615F83982027 for ; Fri, 30 Jul 2021 19:47:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 615F83982027 Received: by mail-pj1-x102c.google.com with SMTP id g23-20020a17090a5797b02901765d605e14so15879186pji.5 for ; Fri, 30 Jul 2021 12:47:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZKwRX28Sj413YBlfQ2sbg6erFk0t3sb+0miIuzYHMpg=; b=p+vj93Huhp2uISftNO/5Y5RhliONqne+fCdMFI64U+AC4V4ivFmVD/yE5maA2+YSbE 9lN/7jnVT70lY/TpOH5IG7XPnSbERPbhYLOkGRttYfzDvLCxo0Ser5MAXSRMjweBJfQy WYlpE2si15sIA6AUDXcvSa0yqfSR/KP38dKfCXiwTtXir8/8eE/Dycz+z8iu4V+4lhDD vwwX+FjVjY6E1bo+ExCCEG16vW35q2MalMJJA49dShqH4Z5yMaLVRh4e1Zb3g+MUusQk 8JCgegEEa+X1fG64T+lN5zj5p2Ep9ptULVF7yT85lsNSb6z2653b+AZT70SHjEsYhOwp N/yg== X-Gm-Message-State: AOAM533oGPy/M6ZMKaIDfMh6Hbh9lbKV/wcaHXMRWq8W1TX8uygK9RjN dOQShU0lBph/hQ5uuc4V1udxunmRZnainQ== X-Google-Smtp-Source: ABdhPJxOsb95QYZ07fhhm0FqEyIASUPdkVgrVf0OpMeZBSd/wukVXlSqp1P7Vh/hd4AmxW/c/c6pmg== X-Received: by 2002:a17:90a:fa0b:: with SMTP id cm11mr4643293pjb.12.1627674477010; Fri, 30 Jul 2021 12:47:57 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:56 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 18/20] elf: Add LA_SYMB_BINDNOW Date: Fri, 30 Jul 2021 16:47:13 -0300 Message-Id: <20210730194715.881900-19-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The warn the audit library that la_symbind() is being invoked in a bind-now manner, a new LA_SYMB_BINDNOW is added. It warns that LA_SYMB_NOPLTENTER nor LA_SYMB_NOPLTEXIT has any effect on PLT tracking. Checked on x86_64-linux-gnu and aarch64-linux-gnu. --- elf/Makefile | 22 +++++++ elf/dl-audit.c | 4 +- elf/dl-runtime.c | 4 +- elf/do-rel.h | 4 +- elf/link.h | 5 +- elf/tst-audit25a.c | 126 ++++++++++++++++++++++++++++++++++++ elf/tst-audit25b.c | 127 +++++++++++++++++++++++++++++++++++++ elf/tst-audit25mod1.c | 30 +++++++++ elf/tst-audit25mod2.c | 30 +++++++++ elf/tst-audit25mod3.c | 22 +++++++ elf/tst-audit25mod4.c | 22 +++++++ elf/tst-auditmod25.c | 77 ++++++++++++++++++++++ sysdeps/generic/ldsodefs.h | 2 +- 13 files changed, 467 insertions(+), 8 deletions(-) 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-auditmod25.c diff --git a/elf/Makefile b/elf/Makefile index bfed7043a5..3e8adeee1d 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -228,6 +228,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit22 \ tst-audit23 \ tst-audit24a tst-audit24b tst-audit24c tst-audit24d \ + tst-audit25a tst-audit25b \ 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 \ @@ -320,6 +321,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod24c \ tst-auditmod24d tst-audit24dmod1 tst-audit24dmod2 \ tst-audit24dmod3 tst-audit24dmod4 \ + tst-auditmod25 tst-audit25mod1 tst-audit25mod2 \ + tst-audit25mod3 tst-audit25mod4 \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ tst-nodelete-zmod \ @@ -1587,6 +1590,25 @@ 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 c3569cb357..920057fd1e 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -190,7 +190,7 @@ rtld_hidden_def (_dl_audit_symbind_alt) 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) + lookup_t result, bool bindnow) { reloc_result->bound = result; /* Compute index of the symbol entry in the symbol table of the DSO with the @@ -217,7 +217,7 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); - unsigned int flags = 0; + unsigned int flags = bindnow ? LA_SYMB_BINDNOW : 0; struct audit_ifaces *afct = GLRO(dl_audit); for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) { diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index a0044b6776..e4b2185795 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -146,7 +146,7 @@ _dl_fixup ( unsigned int init = atomic_load_acquire (&reloc_result->init); if (init == 0) { - _dl_audit_symbind (l, reloc_result, sym, &value, result); + _dl_audit_symbind (l, reloc_result, sym, &value, result, false); /* Store the result for later runs. */ if (__glibc_likely (! GLRO(dl_bind_not))) @@ -321,7 +321,7 @@ _dl_profile_fixup ( auditing libraries the possibility to change the value and tell us whether further auditing is wanted. */ if (defsym != NULL && GLRO(dl_naudit) > 0) - _dl_audit_symbind (l, reloc_result, defsym, &value, result); + _dl_audit_symbind (l, reloc_result, defsym, &value, result, false); #endif /* Store the result for later runs. */ diff --git a/elf/do-rel.h b/elf/do-rel.h index 455e6a8b2e..af14ed3fb3 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -150,7 +150,7 @@ elf_dynamic_do_Rel (struct link_map *map, = RESOLVE_MAP (&sym, rversion, ELF_MACHINE_JMP_SLOT); if (sym != NULL) _dl_audit_symbind (map, &map->l_reloc_result[ri++], sym, - r_addr_arg, sym_map); + r_addr_arg, sym_map, true); } #endif } @@ -199,7 +199,7 @@ elf_dynamic_do_Rel (struct link_map *map, ELF_MACHINE_JMP_SLOT); if (sym != NULL) _dl_audit_symbind (map, &map->l_reloc_result[ri++], sym, - r_addr_arg, sym_map); + r_addr_arg, sym_map, true); } # endif } diff --git a/elf/link.h b/elf/link.h index ff3a85c847..a4cd6864ad 100644 --- a/elf/link.h +++ b/elf/link.h @@ -131,8 +131,11 @@ enum LA_SYMB_NOPLTEXIT = 0x02, /* la_pltexit will not be called. */ LA_SYMB_STRUCTCALL = 0x04, /* Return value is a structure. */ LA_SYMB_DLSYM = 0x08, /* Binding due to dlsym call. */ - LA_SYMB_ALTVALUE = 0x10 /* Value has been changed by a previous + LA_SYMB_ALTVALUE = 0x10, /* Value has been changed by a previous la_symbind call. */ + LA_SYMB_BINDNOW = 0x20, /* The symbol is resolved at loading time + and it will not call neither la_pltenter + not la_pltexit. */ }; struct dl_phdr_info diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c new file mode 100644 index 0000000000..88962091cd --- /dev/null +++ b/elf/tst-audit25a.c @@ -0,0 +1,126 @@ +/* Check DT_AUDIT and LA_SYMB_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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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_BINDNOW. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod3_func1 32\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_BINDNOW. + Also the resolution order is done in breadth-first order. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod4_func1 32\n" + "la_symbind: tst_audit25mod3_func1 32\n" + "la_symbind: tst_audit25mod1_func1 32\n" + "la_symbind: tst_audit25mod2_func1 32\n" + "la_symbind: tst_audit25mod1_func2 32\n" + "la_symbind: tst_audit25mod2_func2 32\n"); + + support_capture_subprocess_free (&result); + } + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c new file mode 100644 index 0000000000..ca441b7ac3 --- /dev/null +++ b/elf/tst-audit25b.c @@ -0,0 +1,127 @@ +/* Check DT_AUDIT and LA_SYMB_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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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_BINDNOW. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod3_func1 32\n" + "la_symbind: tst_audit25mod1_func1 32\n" + "la_symbind: tst_audit25mod2_func1 32\n" + "la_symbind: tst_audit25mod1_func2 32\n" + "la_symbind: tst_audit25mod2_func2 32\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_BINDNOW. + Also the resolution order is done in breadth-first order. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod4_func1 32\n" + "la_symbind: tst_audit25mod3_func1 32\n" + "la_symbind: tst_audit25mod1_func1 32\n" + "la_symbind: tst_audit25mod2_func1 32\n" + "la_symbind: tst_audit25mod1_func2 32\n" + "la_symbind: tst_audit25mod2_func2 32\n"); + + support_capture_subprocess_free (&result); + } + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include 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 + . */ + +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 + . */ + +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 + . */ + +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 + . */ + +void +tst_audit25mod4_func1 (void) +{ +} diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c new file mode 100644 index 0000000000..70b8ec4552 --- /dev/null +++ b/elf/tst-auditmod25.c @@ -0,0 +1,77 @@ +/* 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 + . */ + +#include +#include +#include +#include +#include + +#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 ? map->l_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); + return sym->st_value; +} diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 0958084268..d0d9cf9535 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1372,7 +1372,7 @@ void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); link_map for the symbol resolved. */ 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); + lookup_t result, bool bindnow); /* Same as _dl_audit_symbind(), but called from the dlsym(). The flag LA_SYMB_DLSYM will be set before calling la_symbind() callback. */ void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, From patchwork Fri Jul 30 19:47:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44536 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3C6E9398545C for ; Fri, 30 Jul 2021 20:02:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3C6E9398545C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675328; bh=lGqCVcBS7GcIqlgfGBoV2iCbh+9OOjaJha2WBGzJqtU=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=l6TiFj+2Mw6bAa2Y4+QAwpMMTYnKpLwvHuMbgBKtxklNbXIywBVsT9n7yyOjC5+9b KjTLF55vKrgLBQi4dX6CbeJ77sM41fheWNhnQWu7j+y8p32CbIXRBTP2uNNeO04Xn9 B2XU+hVCL3E8XIC9sqBUOgPUb+XyASQVVvki+ffI= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by sourceware.org (Postfix) with ESMTPS id B0D22397EC1F for ; Fri, 30 Jul 2021 19:47:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B0D22397EC1F Received: by mail-pj1-x1034.google.com with SMTP id b6so16732597pji.4 for ; Fri, 30 Jul 2021 12:47:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lGqCVcBS7GcIqlgfGBoV2iCbh+9OOjaJha2WBGzJqtU=; b=GhX2NJcDMVmAs0EeuWX/ZumnEuTAMVoUXFBAvZy3RvDpcan1g/rN7/Yg8xOVpQYGiB MM9SvrhHXD2rj3hXVzRSJRESdBa8kwKiNWf5gH54+aHcDkSVpq04fmPJe4K7diS0gkEf Sc8fyAmreNnWMwowen7j+Ib1s9hMIl7nlwzd0dm/4vZacLTkOxwMRMFft4gDbe/xKmvt Tdi3eU7OHexeumK2lM9DmcFxo8CgwTOuX7B2H7CdlX6RVTdWal1+syEp2YHuTN2WMhjf z8qkn/KxXb3LclimOWJBmcgg15CeZdZA0OxrIeVaYA4USiCL+gPzDnNy+y4dokjdUQB5 uQQg== X-Gm-Message-State: AOAM531itSzfJ0TXEUcvlFHxiUjdS06yLmcq4/jzFGmC6gk0Io322FjT VxQRDK28bxxQARNAAbWHESS4+XGPCO4zCA== X-Google-Smtp-Source: ABdhPJxJldpSNgvWu/kcJojmP2/noDqePKO9FswcZLI+/G0NtxROYwaakpuLHDZxpJsgMMmLZafMwA== X-Received: by 2002:a17:90b:1495:: with SMTP id js21mr4808000pjb.2.1627674478663; Fri, 30 Jul 2021 12:47:58 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:47:58 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 19/20] elf: Move LAV_CURRENT to link_lavcurrent.h Date: Fri, 30 Jul 2021 16:47:14 -0300 Message-Id: <20210730194715.881900-20-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" No functional change. --- bits/link_lavcurrent.h | 25 +++++++++++++++++++++++++ elf/Makefile | 2 +- elf/link.h | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 bits/link_lavcurrent.h diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h new file mode 100644 index 0000000000..44fbea1e80 --- /dev/null +++ b/bits/link_lavcurrent.h @@ -0,0 +1,25 @@ +/* Data structure for communication from the run-time dynamic linker for + loaded ELF shared objects. LAV_CURRENT definition. + 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 + . */ + +#ifndef _LINK_H +# error "Never include directly; use instead." +#endif + +/* Version numbers for la_version handshake interface. */ +#define LAV_CURRENT 1 diff --git a/elf/Makefile b/elf/Makefile index 3e8adeee1d..2c508c3bfc 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -21,7 +21,7 @@ subdir := elf include ../Makeconfig -headers = elf.h bits/elfclass.h link.h bits/link.h +headers = elf.h bits/elfclass.h link.h bits/link.h bits/link_lavcurrent.h routines = $(all-dl-routines) dl-support dl-iteratephdr \ dl-addr dl-addr-obj enbl-secure dl-profstub \ dl-origin dl-libc dl-sym dl-sysdep dl-error \ diff --git a/elf/link.h b/elf/link.h index a4cd6864ad..af7a38d8fc 100644 --- a/elf/link.h +++ b/elf/link.h @@ -96,7 +96,7 @@ struct link_map #ifdef __USE_GNU /* Version numbers for la_version handshake interface. */ -#define LAV_CURRENT 1 +#include /* Activity types signaled through la_activity. */ enum From patchwork Fri Jul 30 19:47:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44538 X-Patchwork-Delegate: szabolcs.nagy@arm.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 98E273985839 for ; Fri, 30 Jul 2021 20:03:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 98E273985839 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1627675425; bh=LuhCjQmz9rzwpNxRf1hBliVFubC9LjhTIZPbHPgiLe4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=lu2LKctfIbLf2VYyfGtF4mfM3wCziAQepJR0jOm+mHJK7od+bcR0OqiHgSnM+q5Mx ++7thEGEjdagR6pcx1b1Lo6jVPAB+KKZkKqubPuyzHYK1a+3k6mdW+sE6gbwOkNdWc vnu2o8DgOir3jDAe1JGcManwTIYtUsFGza5cpO88= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by sourceware.org (Postfix) with ESMTPS id CD9AF3858C39 for ; Fri, 30 Jul 2021 19:48:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CD9AF3858C39 Received: by mail-pj1-x102f.google.com with SMTP id ds11-20020a17090b08cbb0290172f971883bso22370015pjb.1 for ; Fri, 30 Jul 2021 12:48:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LuhCjQmz9rzwpNxRf1hBliVFubC9LjhTIZPbHPgiLe4=; b=pdDFYeLiuO4ecgHkfP4qVfgT05R71/X5SsZXiY259rdWsBIZHFAVGvh3cRXvlVcHEA sky+uQaDTikhmAuWdSTru2M86rkDCBA8fkTq3iPlbGxZxCpi1GdU4/L+9rl8f2NJl2J4 ZNtTO6FDBW3Sji/Yt5K9i/fh+D3nMQXhFVbkwMW4SDaeWFsif1F0aXsf6zwO2ZXq+0o/ yRgM3x+BWvtVs0k9FNihnrlr59pw3dxpAScG2fp9fywK0tkyFYYmGV4FVKLi79QA5xiP 2zsQc8jYJVdMozbMjRTJtwyKBN0OkXEv9k0ufxX3TeQANiIxKNlTpgxAR6igCi/BP3fe wL6A== X-Gm-Message-State: AOAM532ESpkyG3uoAfCuImgbUdfCrMq3I95TGH9heAIMdN+GHDn5jAI4 ZGyfwoyQj4AnEb8ccQQj+ucX9vi9xpAB8g== X-Google-Smtp-Source: ABdhPJx/W+6vznYMvFm6RYznu7iRvzp00Xvj4oUFD+kYUtRJlH8jSiKJjh7Fi6r0GK/eDi2ql7ZiAQ== X-Received: by 2002:a63:542:: with SMTP id 63mr2137347pgf.359.1627674480458; Fri, 30 Jul 2021 12:48:00 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:43e2:6c33:fd81:e602:d33]) by smtp.gmail.com with ESMTPSA id c12sm3041426pfl.56.2021.07.30.12.47.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 12:48:00 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 20/20] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Date: Fri, 30 Jul 2021 16:47:15 -0300 Message-Id: <20210730194715.881900-21-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210730194715.881900-1-adhemerval.zanella@linaro.org> References: <20210730194715.881900-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" From: Ben Woodard The dynamic linker's auditing was not working on aarch64. There were two distinct problems: 1. _dl_runtime_resolve was not preserving x8 the indirect result location register. 2. The NEON Q registers pushed onto the stack by _dl_runtime_resolve() were twice the size of D registers extracted from the stack frame by _dl_runtime_profile(). To fix it the rtld-auditor interfaces is changed for aarch64: * LAV_CURRENT is bumped to v2 and loader will fail to load audit modules that return a version different than the one supported. * The La_aarch64_regs structure was expanded to include x8 and the full sized NEON V registers that are required to be preserved by the ABI. * dl_runtime_profile needed to extract registers saved by _dl_runtime_resolve and put them into the new correctly sized La_aarch64_regs structure. * The return value structure La_aarch64_retval also did not have the correctly sized NEON V registers. Similar to x86, a new La_aarch64_vector type to represent the NEON register is added on the La_aarch64_regs (so each type can be accessed easier). Checked on aarch64-linux-gnu. Co-authored-by: Adhemerval Zanella --- elf/rtld.c | 4 +- sysdeps/aarch64/Makefile | 20 +++ sysdeps/aarch64/bits/link.h | 24 ++-- sysdeps/aarch64/bits/link_lavcurrent.h | 25 ++++ sysdeps/aarch64/dl-link.sym | 4 +- sysdeps/aarch64/dl-trampoline.S | 90 ++++++++----- sysdeps/aarch64/tst-audit26.c | 37 ++++++ sysdeps/aarch64/tst-audit26mod.c | 33 +++++ sysdeps/aarch64/tst-audit26mod.h | 50 +++++++ sysdeps/aarch64/tst-audit27.c | 64 +++++++++ sysdeps/aarch64/tst-audit27mod.c | 95 ++++++++++++++ sysdeps/aarch64/tst-audit27mod.h | 67 ++++++++++ sysdeps/aarch64/tst-auditmod26.c | 93 +++++++++++++ sysdeps/aarch64/tst-auditmod27.c | 173 +++++++++++++++++++++++++ 14 files changed, 731 insertions(+), 48 deletions(-) create mode 100644 sysdeps/aarch64/bits/link_lavcurrent.h create mode 100644 sysdeps/aarch64/tst-audit26.c create mode 100644 sysdeps/aarch64/tst-audit26mod.c create mode 100644 sysdeps/aarch64/tst-audit26mod.h create mode 100644 sysdeps/aarch64/tst-audit27.c create mode 100644 sysdeps/aarch64/tst-audit27mod.c create mode 100644 sysdeps/aarch64/tst-audit27mod.h create mode 100644 sysdeps/aarch64/tst-auditmod26.c create mode 100644 sysdeps/aarch64/tst-auditmod27.c diff --git a/elf/rtld.c b/elf/rtld.c index 63248c86d0..6299f1b85b 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -988,10 +988,10 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n", return; } - if (lav > LAV_CURRENT) + if (lav != LAV_CURRENT) { _dl_debug_printf ("\ -ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n", +ERROR: audit interface '%s' requires version %d (current supported version %d); ignored.\n", name, lav, LAV_CURRENT); unload_audit_module (dlmargs.map, original_tls_idx); return; diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile index 7c66fb97aa..7183895d04 100644 --- a/sysdeps/aarch64/Makefile +++ b/sysdeps/aarch64/Makefile @@ -10,6 +10,26 @@ endif ifeq ($(subdir),elf) sysdep-dl-routines += dl-bti + +tests += tst-audit26 \ + tst-audit27 + +modules-names += \ + tst-audit26mod \ + tst-auditmod26 \ + tst-audit27mod \ + tst-auditmod27 + +$(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \ + $(objpfx)tst-auditmod26.so +LDFLAGS-tst-audit26 += -Wl,-z,lazy +tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so + +$(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \ + $(objpfx)tst-auditmod27.so +$(objpfx)tst-audit27mod.so: $(libsupport) +LDFLAGS-tst-audit27 += -Wl,-z,lazy +tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so endif ifeq ($(subdir),elf) diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h index 774bbe5f45..2af90ca6be 100644 --- a/sysdeps/aarch64/bits/link.h +++ b/sysdeps/aarch64/bits/link.h @@ -20,23 +20,29 @@ # error "Never include directly; use instead." #endif +typedef union +{ + float s; + double d; + long double q; +} La_aarch64_vector; + /* Registers for entry into PLT on AArch64. */ typedef struct La_aarch64_regs { - uint64_t lr_xreg[8]; - uint64_t lr_dreg[8]; - uint64_t lr_sp; - uint64_t lr_lr; + uint64_t lr_xreg[9]; + La_aarch64_vector lr_vreg[8]; + uint64_t lr_sp; + uint64_t lr_lr; } La_aarch64_regs; /* Return values for calls from PLT on AArch64. */ typedef struct La_aarch64_retval { - /* Up to two integer registers can be used for a return value. */ - uint64_t lrv_xreg[2]; - /* Up to four D registers can be used for a return value. */ - uint64_t lrv_dreg[4]; - + /* Up to eight integer registers can be used for a return value. */ + uint64_t lrv_xreg[8]; + /* Up to eight V registers can be used for a return value. */ + La_aarch64_vector lrv_vreg[8]; } La_aarch64_retval; __BEGIN_DECLS diff --git a/sysdeps/aarch64/bits/link_lavcurrent.h b/sysdeps/aarch64/bits/link_lavcurrent.h new file mode 100644 index 0000000000..c48835d12b --- /dev/null +++ b/sysdeps/aarch64/bits/link_lavcurrent.h @@ -0,0 +1,25 @@ +/* Data structure for communication from the run-time dynamic linker for + loaded ELF shared objects. LAV_CURRENT definition. + 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 + . */ + +#ifndef _LINK_H +# error "Never include directly; use instead." +#endif + +/* Version numbers for la_version handshake interface. */ +#define LAV_CURRENT 2 diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym index d67d28b40c..70d153a1d5 100644 --- a/sysdeps/aarch64/dl-link.sym +++ b/sysdeps/aarch64/dl-link.sym @@ -7,9 +7,9 @@ DL_SIZEOF_RG sizeof(struct La_aarch64_regs) DL_SIZEOF_RV sizeof(struct La_aarch64_retval) DL_OFFSET_RG_X0 offsetof(struct La_aarch64_regs, lr_xreg) -DL_OFFSET_RG_D0 offsetof(struct La_aarch64_regs, lr_dreg) +DL_OFFSET_RG_V0 offsetof(struct La_aarch64_regs, lr_vreg) DL_OFFSET_RG_SP offsetof(struct La_aarch64_regs, lr_sp) DL_OFFSET_RG_LR offsetof(struct La_aarch64_regs, lr_lr) DL_OFFSET_RV_X0 offsetof(struct La_aarch64_retval, lrv_xreg) -DL_OFFSET_RV_D0 offsetof(struct La_aarch64_retval, lrv_dreg) +DL_OFFSET_RV_V0 offsetof(struct La_aarch64_retval, lrv_vreg) diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S index 9b352b1d0f..0f13c4e687 100644 --- a/sysdeps/aarch64/dl-trampoline.S +++ b/sysdeps/aarch64/dl-trampoline.S @@ -45,7 +45,8 @@ _dl_runtime_resolve: cfi_rel_offset (lr, 8) - /* Save arguments. */ + /* Note: Saving x9 is not required by the ABI but the assember requires + the immediate values of operand 3 to be a multiple of 16 */ stp x8, x9, [sp, #-(80+8*16)]! cfi_adjust_cfa_offset (80+8*16) cfi_rel_offset (x8, 0) @@ -142,13 +143,14 @@ _dl_runtime_profile: Stack frame layout: [sp, #...] lr [sp, #...] &PLTGOT[n] - [sp, #96] La_aarch64_regs - [sp, #48] La_aarch64_retval - [sp, #40] frame size return from pltenter - [sp, #32] dl_profile_call saved x1 - [sp, #24] dl_profile_call saved x0 - [sp, #16] t1 - [sp, #0] x29, lr <- x29 + alignment padding 8 bytes + La_aarch64_regs + La_aarch64_retval + frame size return from pltenter + dl_profile_call saved x1 + dl_profile_call saved x0 + t1 + x29, lr <- x29 */ # define OFFSET_T1 16 @@ -183,19 +185,22 @@ _dl_runtime_profile: stp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3] cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0) cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8) - - stp d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0] - cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0) - cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8) - stp d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1] - cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0) - cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8) - stp d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2] - cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0) - cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8) - stp d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3] - cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0) - cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8) + str x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0] + cfi_rel_offset (x8, OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0) + /* Note 8 bytes of padding is in the stack frame for alignment */ + + stp q0, q1, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0] + cfi_rel_offset (q0, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0) + cfi_rel_offset (q1, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0 + 16) + stp q2, q3, [X29, #OFFSET_RG+ DL_OFFSET_RG_V0 + 32*1] + cfi_rel_offset (q2, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 0) + cfi_rel_offset (q3, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 16) + stp q4, q5, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2] + cfi_rel_offset (q4, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 0) + cfi_rel_offset (q5, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 16) + stp q6, q7, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3] + cfi_rel_offset (q6, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 0) + cfi_rel_offset (q7, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 16) add x0, x29, #SF_SIZE + 16 ldr x1, [x29, #OFFSET_LR] @@ -234,10 +239,11 @@ _dl_runtime_profile: ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1] ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2] ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3] - ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0] - ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1] - ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2] - ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3] + ldr x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] + ldp q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0] + ldp q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1] + ldp q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2] + ldp q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3] cfi_def_cfa_register (sp) ldp x29, x30, [x29, #0] @@ -280,14 +286,21 @@ _dl_runtime_profile: ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1] ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2] ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3] - ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0] - ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1] - ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2] - ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3] + ldr x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] + ldp q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0] + ldp q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1] + ldp q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2] + ldp q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3] blr ip0 - stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0] - stp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0] - stp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1] + stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0] + stp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1] + stp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2] + stp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3] + str x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4] + stp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0] + stp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1] + stp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2] + stp q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3] /* Setup call to pltexit */ ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0] @@ -295,9 +308,16 @@ _dl_runtime_profile: add x3, x29, #OFFSET_RV bl _dl_audit_pltexit - ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0] - ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0] - ldp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1] + ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0] + ldp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3] + ldr x8, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4] + ldp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0] + ldp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1] + ldp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2] + ldp q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3] + /* LR from within La_aarch64_reg */ ldr lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR] cfi_restore(lr) diff --git a/sysdeps/aarch64/tst-audit26.c b/sysdeps/aarch64/tst-audit26.c new file mode 100644 index 0000000000..44d2479e08 --- /dev/null +++ b/sysdeps/aarch64/tst-audit26.c @@ -0,0 +1,37 @@ +/* Check DT_AUDIT for aarch64 ABI specifics. + 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 "tst-audit26mod.h" + +int +do_test (void) +{ + /* Returning a large struct uses 'x8' as indirect result location. */ + struct large_struct r = tst_audit26_func (ARG1, ARG2, ARG3); + + struct large_struct e = set_large_struct (ARG1, ARG2, ARG3); + + TEST_COMPARE_BLOB (r.a, sizeof (r.a), e.a, sizeof (e.a)); + + return 0; +} + +#include diff --git a/sysdeps/aarch64/tst-audit26mod.c b/sysdeps/aarch64/tst-audit26mod.c new file mode 100644 index 0000000000..f8d9270898 --- /dev/null +++ b/sysdeps/aarch64/tst-audit26mod.c @@ -0,0 +1,33 @@ +/* Check DT_AUDIT for aarch64 ABI specifics. + 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 "tst-audit26mod.h" + +struct large_struct +tst_audit26_func (char a, short b, long int c) +{ + if (a != ARG1) + abort (); + if (b != ARG2) + abort (); + if (c != ARG3) + abort (); + + return set_large_struct (a, b, c); +} diff --git a/sysdeps/aarch64/tst-audit26mod.h b/sysdeps/aarch64/tst-audit26mod.h new file mode 100644 index 0000000000..dd9ddcdada --- /dev/null +++ b/sysdeps/aarch64/tst-audit26mod.h @@ -0,0 +1,50 @@ +/* Check DT_AUDIT for aarch64 specific ABI. + 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 + . */ + +#ifndef _TST_AUDIT27MOD_H +#define _TST_AUDIT27MOD_H 1 + +#include + +struct large_struct +{ + char a[16]; + short b[8]; + long int c[4]; +}; + +static inline struct large_struct +set_large_struct (char a, short b, long int c) +{ + struct large_struct r; + for (int i = 0; i < array_length (r.a); i++) + r.a[i] = a; + for (int i = 0; i < array_length (r.b); i++) + r.b[i] = b; + for (int i = 0; i < array_length (r.c); i++) + r.c[i] = c; + return r; +} + +#define ARG1 0x12 +#define ARG2 0x1234 +#define ARG3 0x12345678 + +struct large_struct tst_audit26_func (char a, short b, long int c); + +#endif diff --git a/sysdeps/aarch64/tst-audit27.c b/sysdeps/aarch64/tst-audit27.c new file mode 100644 index 0000000000..e19b58bc3b --- /dev/null +++ b/sysdeps/aarch64/tst-audit27.c @@ -0,0 +1,64 @@ +/* Check DT_AUDIT for aarch64 ABI specifics. + 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 "tst-audit27mod.h" + +int +do_test (void) +{ + { + float r = tst_audit27_func_float (FUNC_FLOAT_ARG0, FUNC_FLOAT_ARG1, + FUNC_FLOAT_ARG2, FUNC_FLOAT_ARG3, + FUNC_FLOAT_ARG4, FUNC_FLOAT_ARG5, + FUNC_FLOAT_ARG6, FUNC_FLOAT_ARG7); + if (r != FUNC_FLOAT_RET) + FAIL_EXIT1 ("tst_audit27_func_float() returned %a, expected %a", + r, FUNC_FLOAT_RET); + } + + { + double r = tst_audit27_func_double (FUNC_DOUBLE_ARG0, FUNC_DOUBLE_ARG1, + FUNC_DOUBLE_ARG2, FUNC_DOUBLE_ARG3, + FUNC_DOUBLE_ARG4, FUNC_DOUBLE_ARG5, + FUNC_DOUBLE_ARG6, FUNC_DOUBLE_ARG7); + if (r != FUNC_DOUBLE_RET) + FAIL_EXIT1 ("tst_audit27_func_double() returned %la, expected %la", + r, FUNC_DOUBLE_RET); + } + + { + long double r = tst_audit27_func_ldouble (FUNC_LDOUBLE_ARG0, + FUNC_LDOUBLE_ARG1, + FUNC_LDOUBLE_ARG2, + FUNC_LDOUBLE_ARG3, + FUNC_LDOUBLE_ARG4, + FUNC_LDOUBLE_ARG5, + FUNC_LDOUBLE_ARG6, + FUNC_LDOUBLE_ARG7); + if (r != FUNC_LDOUBLE_RET) + FAIL_EXIT1 ("tst_audit27_func_ldouble() returned %La, expected %La", + r, FUNC_LDOUBLE_RET); + } + + return 0; +} + +#include diff --git a/sysdeps/aarch64/tst-audit27mod.c b/sysdeps/aarch64/tst-audit27mod.c new file mode 100644 index 0000000000..9adbf3c778 --- /dev/null +++ b/sysdeps/aarch64/tst-audit27mod.c @@ -0,0 +1,95 @@ +/* Check DT_AUDIT for aarch64 ABI specifics. + 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 "tst-audit27mod.h" + +float +tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4, + float a5, float a6, float a7) +{ + if (a0 != FUNC_FLOAT_ARG0) + FAIL_EXIT1 ("a0: %a != %a", a0, FUNC_FLOAT_ARG0); + if (a1 != FUNC_FLOAT_ARG1) + FAIL_EXIT1 ("a1: %a != %a", a1, FUNC_FLOAT_ARG1); + if (a2 != FUNC_FLOAT_ARG2) + FAIL_EXIT1 ("a2: %a != %a", a2, FUNC_FLOAT_ARG2); + if (a3 != FUNC_FLOAT_ARG3) + FAIL_EXIT1 ("a3: %a != %a", a3, FUNC_FLOAT_ARG3); + if (a4 != FUNC_FLOAT_ARG4) + FAIL_EXIT1 ("a4: %a != %a", a4, FUNC_FLOAT_ARG4); + if (a5 != FUNC_FLOAT_ARG5) + FAIL_EXIT1 ("a5: %a != %a", a5, FUNC_FLOAT_ARG5); + if (a6 != FUNC_FLOAT_ARG6) + FAIL_EXIT1 ("a6: %a != %a", a6, FUNC_FLOAT_ARG6); + if (a7 != FUNC_FLOAT_ARG7) + FAIL_EXIT1 ("a7: %a != %a", a7, FUNC_FLOAT_ARG7); + + return FUNC_FLOAT_RET; +} + +double +tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4, + double a5, double a6, double a7) +{ + if (a0 != FUNC_DOUBLE_ARG0) + FAIL_EXIT1 ("a0: %la != %la", a0, FUNC_DOUBLE_ARG0); + if (a1 != FUNC_DOUBLE_ARG1) + FAIL_EXIT1 ("a1: %la != %la", a1, FUNC_DOUBLE_ARG1); + if (a2 != FUNC_DOUBLE_ARG2) + FAIL_EXIT1 ("a2: %la != %la", a2, FUNC_DOUBLE_ARG2); + if (a3 != FUNC_DOUBLE_ARG3) + FAIL_EXIT1 ("a3: %la != %la", a3, FUNC_DOUBLE_ARG3); + if (a4 != FUNC_DOUBLE_ARG4) + FAIL_EXIT1 ("a4: %la != %la", a4, FUNC_DOUBLE_ARG4); + if (a5 != FUNC_DOUBLE_ARG5) + FAIL_EXIT1 ("a5: %la != %la", a5, FUNC_DOUBLE_ARG5); + if (a6 != FUNC_DOUBLE_ARG6) + FAIL_EXIT1 ("a6: %la != %la", a6, FUNC_DOUBLE_ARG6); + if (a7 != FUNC_DOUBLE_ARG7) + FAIL_EXIT1 ("a7: %la != %la", a7, FUNC_DOUBLE_ARG7); + + return FUNC_DOUBLE_RET; +} + +long double +tst_audit27_func_ldouble (long double a0, long double a1, long double a2, + long double a3, long double a4, long double a5, + long double a6, long double a7) +{ + if (a0 != FUNC_LDOUBLE_ARG0) + FAIL_EXIT1 ("a0: %La != %La", a0, FUNC_LDOUBLE_ARG0); + if (a1 != FUNC_LDOUBLE_ARG1) + FAIL_EXIT1 ("a1: %La != %La", a1, FUNC_LDOUBLE_ARG1); + if (a2 != FUNC_LDOUBLE_ARG2) + FAIL_EXIT1 ("a2: %La != %La", a2, FUNC_LDOUBLE_ARG2); + if (a3 != FUNC_LDOUBLE_ARG3) + FAIL_EXIT1 ("a3: %La != %La", a3, FUNC_LDOUBLE_ARG3); + if (a4 != FUNC_LDOUBLE_ARG4) + FAIL_EXIT1 ("a4: %La != %La", a4, FUNC_LDOUBLE_ARG4); + if (a5 != FUNC_LDOUBLE_ARG5) + FAIL_EXIT1 ("a5: %La != %La", a5, FUNC_LDOUBLE_ARG5); + if (a6 != FUNC_LDOUBLE_ARG6) + FAIL_EXIT1 ("a6: %La != %La", a6, FUNC_LDOUBLE_ARG6); + if (a7 != FUNC_LDOUBLE_ARG7) + FAIL_EXIT1 ("a7: %La != %La", a7, FUNC_LDOUBLE_ARG7); + + return FUNC_LDOUBLE_RET; +} diff --git a/sysdeps/aarch64/tst-audit27mod.h b/sysdeps/aarch64/tst-audit27mod.h new file mode 100644 index 0000000000..7038c90719 --- /dev/null +++ b/sysdeps/aarch64/tst-audit27mod.h @@ -0,0 +1,67 @@ +/* Check DT_AUDIT for aarch64 specific ABI. + 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 + . */ + +#ifndef _TST_AUDIT27MOD_H +#define _TST_AUDIT27MOD_H 1 + +#include + +#define FUNC_FLOAT_ARG0 FLT_MIN +#define FUNC_FLOAT_ARG1 FLT_MAX +#define FUNC_FLOAT_ARG2 FLT_EPSILON +#define FUNC_FLOAT_ARG3 FLT_TRUE_MIN +#define FUNC_FLOAT_ARG4 0.0f +#define FUNC_FLOAT_ARG5 1.0f +#define FUNC_FLOAT_ARG6 2.0f +#define FUNC_FLOAT_ARG7 3.0f +#define FUNC_FLOAT_RET 4.0f + +float +tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4, + float a5, float a6, float a7); + +#define FUNC_DOUBLE_ARG0 DBL_MIN +#define FUNC_DOUBLE_ARG1 DBL_MAX +#define FUNC_DOUBLE_ARG2 DBL_EPSILON +#define FUNC_DOUBLE_ARG3 DBL_TRUE_MIN +#define FUNC_DOUBLE_ARG4 0.0 +#define FUNC_DOUBLE_ARG5 1.0 +#define FUNC_DOUBLE_ARG6 2.0 +#define FUNC_DOUBLE_ARG7 3.0 +#define FUNC_DOUBLE_RET 0x1.fffffe0000001p+127 + +double +tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4, + double a5, double a6, double a7); + +#define FUNC_LDOUBLE_ARG0 DBL_MAX + 1.0L +#define FUNC_LDOUBLE_ARG1 DBL_MAX + 2.0L +#define FUNC_LDOUBLE_ARG2 DBL_MAX + 3.0L +#define FUNC_LDOUBLE_ARG3 DBL_MAX + 4.0L +#define FUNC_LDOUBLE_ARG4 DBL_MAX + 5.0L +#define FUNC_LDOUBLE_ARG5 DBL_MAX + 6.0L +#define FUNC_LDOUBLE_ARG6 DBL_MAX + 7.0L +#define FUNC_LDOUBLE_ARG7 DBL_MAX + 8.0L +#define FUNC_LDOUBLE_RET 0x1.fffffffffffff000000000000001p+1023L + +long double +tst_audit27_func_ldouble (long double a0, long double a1, long double a2, + long double a3, long double a4, long double a5, + long double a6, long double a7); + +#endif diff --git a/sysdeps/aarch64/tst-auditmod26.c b/sysdeps/aarch64/tst-auditmod26.c new file mode 100644 index 0000000000..0fcb7a07f2 --- /dev/null +++ b/sysdeps/aarch64/tst-auditmod26.c @@ -0,0 +1,93 @@ +/* Check DT_AUDIT for aarch64 specific ABI. + 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 "tst-audit26mod.h" + +#define TEST_NAME "tst-audit26" + +#define AUDIT26_COOKIE 0 + +unsigned int +la_version (unsigned int v) +{ + return v; +} + +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 ? map->l_name : p + 1; + uintptr_t ck = -1; + if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) + ck = AUDIT26_COOKIE; + *cookie = ck; + printf ("objopen: %ld, %s\n", lmid, l_name); + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; +} + +ElfW(Addr) +la_aarch64_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_aarch64_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + if (strcmp (symname, "tst_audit26_func") == 0) + { + assert (regs->lr_xreg[0] == ARG1); + assert (regs->lr_xreg[1] == ARG2); + assert (regs->lr_xreg[2] == ARG3); + } + else + abort (); + + /* Clobber 'x8'. */ + asm volatile ("mov x8, -1" : : : "x8"); + + return sym->st_value; +} + +unsigned int +la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, + const struct La_aarch64_regs *inregs, + struct La_aarch64_retval *outregs, const char *symname) +{ + if (strcmp (symname, "tst_audit26_func") == 0) + { + assert (inregs->lr_xreg[0] == ARG1); + assert (inregs->lr_xreg[1] == ARG2); + assert (inregs->lr_xreg[2] == ARG3); + } + else + abort (); + + /* Clobber 'x8'. */ + asm volatile ("mov x8, -1" : : : "x8"); + + return 0; +} diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c new file mode 100644 index 0000000000..1cf76371b5 --- /dev/null +++ b/sysdeps/aarch64/tst-auditmod27.c @@ -0,0 +1,173 @@ +/* Check DT_AUDIT for aarch64 specific ABI. + 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 "tst-audit27mod.h" + +#define TEST_NAME "tst-audit27" + +#define AUDIT27_COOKIE 0 + +unsigned int +la_version (unsigned int v) +{ + return v; +} + +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 ? map->l_name : p + 1; + uintptr_t ck = -1; + if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0) + ck = AUDIT27_COOKIE; + *cookie = ck; + printf ("objopen: %ld, %s\n", lmid, l_name); + return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO; +} + +ElfW(Addr) +la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_aarch64_regs *regs, + unsigned int *flags, const char *symname, + long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + if (strcmp (symname, "tst_audit27_func_float") == 0) + { + assert (regs->lr_vreg[0].s == FUNC_FLOAT_ARG0); + assert (regs->lr_vreg[1].s == FUNC_FLOAT_ARG1); + assert (regs->lr_vreg[2].s == FUNC_FLOAT_ARG2); + assert (regs->lr_vreg[3].s == FUNC_FLOAT_ARG3); + assert (regs->lr_vreg[4].s == FUNC_FLOAT_ARG4); + assert (regs->lr_vreg[5].s == FUNC_FLOAT_ARG5); + assert (regs->lr_vreg[6].s == FUNC_FLOAT_ARG6); + assert (regs->lr_vreg[7].s == FUNC_FLOAT_ARG7); + } + else if (strcmp (symname, "tst_audit27_func_double") == 0) + { + assert (regs->lr_vreg[0].d == FUNC_DOUBLE_ARG0); + assert (regs->lr_vreg[1].d == FUNC_DOUBLE_ARG1); + assert (regs->lr_vreg[2].d == FUNC_DOUBLE_ARG2); + assert (regs->lr_vreg[3].d == FUNC_DOUBLE_ARG3); + assert (regs->lr_vreg[4].d == FUNC_DOUBLE_ARG4); + assert (regs->lr_vreg[5].d == FUNC_DOUBLE_ARG5); + assert (regs->lr_vreg[6].d == FUNC_DOUBLE_ARG6); + assert (regs->lr_vreg[7].d == FUNC_DOUBLE_ARG7); + } + else if (strcmp (symname, "tst_audit27_func_ldouble") == 0) + { + assert (regs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0); + assert (regs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1); + assert (regs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2); + assert (regs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3); + assert (regs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4); + assert (regs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5); + assert (regs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6); + assert (regs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7); + } + else + abort (); + + /* Clobber the q registers on exit. */ + uint8_t v = 0xff; + asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v0"); + + return sym->st_value; +} + +unsigned int +la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, + const struct La_aarch64_regs *inregs, + struct La_aarch64_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n", + symname, (long int) sym->st_value, ndx); + + if (strcmp (symname, "tst_audit27_func_float") == 0) + { + assert (inregs->lr_vreg[0].s == FUNC_FLOAT_ARG0); + assert (inregs->lr_vreg[1].s == FUNC_FLOAT_ARG1); + assert (inregs->lr_vreg[2].s == FUNC_FLOAT_ARG2); + assert (inregs->lr_vreg[3].s == FUNC_FLOAT_ARG3); + assert (inregs->lr_vreg[4].s == FUNC_FLOAT_ARG4); + assert (inregs->lr_vreg[5].s == FUNC_FLOAT_ARG5); + assert (inregs->lr_vreg[6].s == FUNC_FLOAT_ARG6); + assert (inregs->lr_vreg[7].s == FUNC_FLOAT_ARG7); + + assert (outregs->lrv_vreg[0].s == FUNC_FLOAT_RET); + } + else if (strcmp (symname, "tst_audit27_func_double") == 0) + { + assert (inregs->lr_vreg[0].d == FUNC_DOUBLE_ARG0); + assert (inregs->lr_vreg[1].d == FUNC_DOUBLE_ARG1); + assert (inregs->lr_vreg[2].d == FUNC_DOUBLE_ARG2); + assert (inregs->lr_vreg[3].d == FUNC_DOUBLE_ARG3); + assert (inregs->lr_vreg[4].d == FUNC_DOUBLE_ARG4); + assert (inregs->lr_vreg[5].d == FUNC_DOUBLE_ARG5); + assert (inregs->lr_vreg[6].d == FUNC_DOUBLE_ARG6); + assert (inregs->lr_vreg[7].d == FUNC_DOUBLE_ARG7); + + assert (outregs->lrv_vreg[0].s == FUNC_DOUBLE_RET); + } + else if (strcmp (symname, "tst_audit27_func_ldouble") == 0) + { + assert (inregs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0); + assert (inregs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1); + assert (inregs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2); + assert (inregs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3); + assert (inregs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4); + assert (inregs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5); + assert (inregs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6); + assert (inregs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7); + + assert (outregs->lrv_vreg[0].s == FUNC_LDOUBLE_RET); + } + else + abort (); + + /* Clobber the q registers on exit. */ + uint8_t v = 0xff; + asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v0"); + asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v0"); + + return 0; +}