From patchwork Thu Oct 14 17:47:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46225 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 2286A3858025 for ; Thu, 14 Oct 2021 17:49:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2286A3858025 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634233787; bh=2itPpIaxSTwFwcDkvw9u+WMFbHwIehG+nPEUceOMH/k=; 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=hPSAk7t8bhQo8Dv6YhPVa+CmysY7v1H2g3RYTgKkVvd7zgnk6AlvUqdWrg+KeFDWH amnLNpLOWDeO8l/c2c98RVpnPGaLlhgmetB5R6MR+icLDLGntrO9ltnWUzKDDnhUEs wJg9xoZ608kjx4Pd+G9I6XVvGEKKplB0TudPV8b0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x929.google.com (mail-ua1-x929.google.com [IPv6:2607:f8b0:4864:20::929]) by sourceware.org (Postfix) with ESMTPS id 91F2D3858419 for ; Thu, 14 Oct 2021 17:48:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 91F2D3858419 Received: by mail-ua1-x929.google.com with SMTP id q13so12944436uaq.2 for ; Thu, 14 Oct 2021 10:48:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2itPpIaxSTwFwcDkvw9u+WMFbHwIehG+nPEUceOMH/k=; b=1etDwCCgu4WCWj7SaacxM7bY+KqWmRTFb7v7zjnhG420E68sUkU0T/dltydbgPNfBQ /cF38+DxHNpc4rTczfHCc3UCJy2o9pJLVRT4a49HNqnyy0y9LkU3Kxevh6WaIuKeumDX vS/0r24Db7JcGQDt7sevUKX+/SJJieETto8ulQi5j+m/yaI/vB+RYpWzGj+Q+gnkWN4m tDBlMBt5WjAaxR/xhQZhzyVCfUguelUeEKoySLKfpzk3P+Efy+tynv28Nl0ymbMm67Kf rA4PFt+KMTaahRk6nDdMXROAfY1U2NguNSKeBcjXAcilvUTSLWhhEZXSL/ZdlkuBpv84 2B9w== X-Gm-Message-State: AOAM531TmcE+ERgbKEsMX31jJnsWL5/53yZQvi5zFVOfyUEC7oDAef1a KxlebWoRHyNFH28iJaU8HvVaxEenLvF4dQ== X-Google-Smtp-Source: ABdhPJx7seanIp5DLB3DQTRck41fFgQiXdvKbsDj5rxCILyt8/vaWa/N6wZvYCp132zX9GoM2EUH6g== X-Received: by 2002:a05:6102:3ec3:: with SMTP id n3mr8453138vsv.48.1634233679590; Thu, 14 Oct 2021 10:47:59 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.47.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:47:59 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 01/21] elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) Date: Thu, 14 Oct 2021 14:47:32 -0300 Message-Id: <20211014174752.1651347-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 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 Netto Reply-To: Adhemerval Zanella Cc: Alexander Monakov , 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, i686-linux-gnu, and aarch64-linux-gnu. --- NEWS | 4 + elf/Makefile | 10 +++ 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, 385 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 220d327071..c95925d0b7 100644 --- a/NEWS +++ b/NEWS @@ -167,6 +167,10 @@ Major new features: than or equal to a given integer. This function is a GNU extension, although Solaris also provides a similar function. +* The audit libraries will avoid unnecessary slowdown if it is not required + PLT tracking (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 bf45d8ee24..b718d31524 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -220,6 +220,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \ 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 \ @@ -308,6 +310,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 \ @@ -1506,6 +1509,13 @@ $(objpfx)tst-audit16-cmp.out: tst-audit16.exp $(objpfx)tst-audit16.out cmp $^ > $@; \ $(evaluate-test) +$(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 0d5b727c64..27f792b7b2 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -203,11 +203,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 @@ -272,7 +286,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], ELF_DYNAMIC_RELOCATE (l, scope, 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 61c260ddb8..b0c788eb22 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -44,6 +44,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 @@ -139,6 +217,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; @@ -297,84 +406,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 6cfb7cf672..4bbf71b587 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1014,13 +1014,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 484ee6cb1b..5b29a4f992 100644 --- a/include/link.h +++ b/include/link.h @@ -362,8 +362,10 @@ extern struct r_debug_extended _r_debug_extended attribute_hidden; #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 Thu Oct 14 17:47:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46224 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 D54083857C47 for ; Thu, 14 Oct 2021 17:49:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D54083857C47 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634233744; bh=+DWS1dPh/PA/k2rKolmOn/jgWKFkeEjWUjobhFRmsrU=; 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=M7+vbtTLJukTbgneXevU9vewlGiMlycjpZ3BKKtwb6HuVgEgy60tic8uunfVYFdo3 7rNotO3cJE48bmN7YsifRaCSce+fVSCQ6h3kvNyrpzE/YgaAT3C5dXzl3U9XiyAInS hSxCeyHQAnucmqGZFayDOIRmQrK/pjpV0Z15Ilug= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa29.google.com (mail-vk1-xa29.google.com [IPv6:2607:f8b0:4864:20::a29]) by sourceware.org (Postfix) with ESMTPS id 9B8BB3858427 for ; Thu, 14 Oct 2021 17:48:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9B8BB3858427 Received: by mail-vk1-xa29.google.com with SMTP id m199so3884907vka.6 for ; Thu, 14 Oct 2021 10:48:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+DWS1dPh/PA/k2rKolmOn/jgWKFkeEjWUjobhFRmsrU=; b=1a3Sr2/VJ2c9BbNtM3TRG1onNSv/Z/UDzPoPma+QHK9I2RK7b8RWhkarXp5DxJ7HLq k2IhSfuIBYyfbidh/ujDkMvce9z6S3+dWsOmSJj95V8ASv/CWpRff3J2ejYhvaK+5KqU HOCBAzIPoqvAjY0dXv/eAyP55AbKFhKXF7Mwb/Dnt1NshWU9u+x5Y/YjHPDBKUmvbG7K jrvvh0XARxWxU1BgWk9P8TCa8kN135oj8O2oWV121fYvviehgEtecl9S94goQDHvITsY xg+UJkHfI8neUCM+kh6S7LnH39sOY7a5cvXDxkw/PxqLBXbaSTH4yLQ2u+mPDGClGgxx EtFA== X-Gm-Message-State: AOAM531LXVcBnLQZUETT5UI0CIetwc9iTxMr1wHlUuJ2CzRZ2fIuk28p 7pzwGeShdBojbD8yQ/RFzNVOP1gt9noLwg== X-Google-Smtp-Source: ABdhPJxRXQEGrKCdrrILaKlmtrxi/ApY/8oylnq6yczkbNCsHqjNKt4IKKLLj7zSf1M7Scz3eUkAbw== X-Received: by 2002:a1f:1e06:: with SMTP id e6mr7926477vke.24.1634233681022; Thu, 14 Oct 2021 10:48:01 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.47.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:00 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 02/21] elf: Add audit tests for modules with TLSDESC Date: Thu, 14 Oct 2021 14:47:33 -0300 Message-Id: <20211014174752.1651347-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Netto Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. --- 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 b718d31524..378567de67 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -380,6 +380,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 Thu Oct 14 17:47:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46226 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 928D13858015 for ; Thu, 14 Oct 2021 17:50:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 928D13858015 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634233836; bh=37w9dw5NATByBh//0oFuAk+sBadl95MbVi26a/mOFO4=; 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=GWriUmkhjaoP4yfEvU5660d0hHq1KvBq2DkuCk6vZUaZH1/ZOl8TBYjJTQJRfYmeb t2fsPvq5842D0arWsB3EzIeEGG9RmjrVA8OW9vgN2M9/n1W4CfDn/Gh+TfDRMraSki 1jyNaiWiKmsrnLXFVO/yfesNZe/S3Hv9t/hlTJUM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x929.google.com (mail-ua1-x929.google.com [IPv6:2607:f8b0:4864:20::929]) by sourceware.org (Postfix) with ESMTPS id E99C03858433 for ; Thu, 14 Oct 2021 17:48:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E99C03858433 Received: by mail-ua1-x929.google.com with SMTP id f3so12899578uap.6 for ; Thu, 14 Oct 2021 10:48:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=37w9dw5NATByBh//0oFuAk+sBadl95MbVi26a/mOFO4=; b=LqnJfaoD4AGgNln9lrmpoZ41E5tv2t8EfqjbJwfpZs5aZhCJ0dnertJz/xD+Po2z4Q ux0pvRPo94zIztjwVsKNSKPAS7ZVBE8FT6dQpbjcv24lCJWaSR4HS37xz4xKtBTr8G8q uvHZ1LF3DFOdy5E0nvfrFVtMc8cMQKkQbj0wTHgB0nkbNnysf1xhHc8UxhquuqItuIc/ cfAI4I0B03pOQJICgjd3ko1Vlx2bEZO3e6z9UI+6g8b7kaCAzdLQf6zwLy9KyKAGZJda yjR/bi1FzLttph7i/bA79uZVgnN2FN2etIElpdyOhSOmk0GvR+Seee0WND+Nw2VuIBOc 44Uw== X-Gm-Message-State: AOAM531EA0K/1r2zCf1LUjhyUKZF4ST0dXx6i4tNzrWsrlQWGdbqg2eP cpZ+kvUOji3SyjHcR3wHOZR/H++NQi4= X-Google-Smtp-Source: ABdhPJzwqO6sVBXwwmLmsNu37JMUz5Faork9jnfCeaYd5R71pSRo8agxHWn2bGtMQ7egdcbivyCQYA== X-Received: by 2002:a67:26c2:: with SMTP id m185mr8473506vsm.2.1634233682391; Thu, 14 Oct 2021 10:48:02 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:02 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 03/21] elf: Do not fail for failed dlopem on audit modules (BZ #28061) Date: Thu, 14 Oct 2021 14:47:34 -0300 Message-Id: <20211014174752.1651347-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 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 Netto 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 add 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 first it will not use LM_ID_BASE and second _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, i686-linux-gnu, and aarch64-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 378567de67..fc8d6d44ab 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -222,6 +222,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 \ @@ -311,6 +312,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 \ @@ -1530,6 +1532,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 6ea5dd2457..00f6d8cfcc 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -932,8 +932,6 @@ no more namespaces available for dlmopen()")); the flag here. */ } - assert (_dl_debug_update (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 Thu Oct 14 17:47:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46227 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 872F53857C53 for ; Thu, 14 Oct 2021 17:51:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 872F53857C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634233878; bh=OZvoNnJr+bL9HD8EDaYB1xJiL2esct10OV09bmTUMu4=; 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=DATWFQ0i6TI7W9mLQJ2qO0Ml9HXovJcYNeUGtdjQ2IGMdYHBmePah5+ZhotU6v2A+ jo/NXEuA2AnlL79vyLDyCo2VMQwlKKguOUmaRE4YiD8/vlefQGmLnbAIz+jJUxLKIh Yti/D/QNR/hdkPv1WhlAN4SvEVLQXfhdd4SyPqrI= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x935.google.com (mail-ua1-x935.google.com [IPv6:2607:f8b0:4864:20::935]) by sourceware.org (Postfix) with ESMTPS id 4D1B23857C4C for ; Thu, 14 Oct 2021 17:48:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4D1B23857C4C Received: by mail-ua1-x935.google.com with SMTP id r17so12884079uaf.8 for ; Thu, 14 Oct 2021 10:48:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OZvoNnJr+bL9HD8EDaYB1xJiL2esct10OV09bmTUMu4=; b=OIcJFDUGRGC4be1F2bhfZmPYE/2UgthjWIzVjVzb1u/MrapyezhwqwdEt1Ki+SsjgD xR5ZYK+nbiU68ZwUDy+6TNUKJXYi4nU0AL00NHqWIF1G709u1RnJzdKggzK1LNbrFwR6 PqnHd+vAVuJzJ6PbqEklf/HJVELJ0fp6hs75dAycPefH3knbFv/4tWCJjPf5293B6Pra AUkdTsSiRuE1yYxRcBPkVEspcSLH0b0dDy6+Ro9qo3e4CxjTGKrxzrgp5DiVgRdFpdrt T6h1sg/o1xZetGCLbp2EMydICTpnBTcj7FB+YlKJhQdklZlutnXHfYDHCZ5t2pedCF8y KXrg== X-Gm-Message-State: AOAM533e2H30wSXhBQwcmxwDwtdFc5zP+dlFdT4XVKu1nWe4dKizymEW 6JoF8ZSsc5DVmTXZQ0rGjZjtsvfvKyWOkQ== X-Google-Smtp-Source: ABdhPJwajfYg1JV8MuZOoWojw6ch8Tp1Gp9yxqquS2cjrmcsEOoSKj8fGKCu9DNRpk407x1/zLpZrg== X-Received: by 2002:a05:6102:1d2:: with SMTP id s18mr8565333vsq.42.1634233685663; Thu, 14 Oct 2021 10:48:05 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:05 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 04/21] elf: Suppress audit calls when a (new) namespace is empty (BZ #28062) Date: Thu, 14 Oct 2021 14:47:35 -0300 Message-Id: <20211014174752.1651347-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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 are empty, so it requires to check 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 fc8d6d44ab..549bd30c7d 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -223,6 +223,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 \ @@ -313,6 +314,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 \ @@ -1535,6 +1537,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 18d3e8fe64..6324fc707c 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1067,8 +1067,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 Thu Oct 14 17:47:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46228 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 7900A3858427 for ; Thu, 14 Oct 2021 17:52:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7900A3858427 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634233920; bh=uVFKphTkKIkAD2fumvUOdXlKfOSc7fIonTMEPJvXCh8=; 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=iYncYl4TPMrFUYr+EKoePtqZRo6nyD9+6jje/T6NlOHE3+bKtZAMpaQsy+mZZi0E1 b8EJe1ca1p6v1UufChgcHWOPkVjhSAHmvU11hHIPLb7xihOx42b5eKvo8YY0IT0vAw jXwm5KYi1KiV/xJsoE3JXxpMcbP2ysQtwFidXCmg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x929.google.com (mail-ua1-x929.google.com [IPv6:2607:f8b0:4864:20::929]) by sourceware.org (Postfix) with ESMTPS id C08013857C42 for ; Thu, 14 Oct 2021 17:48:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C08013857C42 Received: by mail-ua1-x929.google.com with SMTP id f4so12918353uad.4 for ; Thu, 14 Oct 2021 10:48:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uVFKphTkKIkAD2fumvUOdXlKfOSc7fIonTMEPJvXCh8=; b=Ym6WxsY2NmwHjb8MnGivDRo5z+HM9JsYpRaroJBvIBvWxuWyLhLqpccEQCYhsa1jai 5OSj+YDf3sq+OS2EPghJmev9uouHea0tG1rYM2bwX4pIhQWgdwuOF0m9hKgzcrCmRS+8 U9K5ioJoJMXu3wwrp6Mj8cpH5XS6DA7OCnG5/raigJwUuNgssxt7AfIyfdEDItI8RT1R feodv9bwWFQT49QByoBX+eP3NNysFSL0FdwRFIYx5lY5dwD8g9uMd0L6x2yNKXnZeDOh 5lRs8sygzE6HtowmoriUo31qIbJftWuUh6PI+yJ0DKQq7HHfRa3qQUcYG7PCvbvQFhFx i1yw== X-Gm-Message-State: AOAM5300/STB7U1pSR1cW6XawTzT//2TkqbAOY5YS5s5ekJ/5kMaQxO2 /zgNbhrY+0c3ZHf1CRTw7FtKtFCcPcTphA== X-Google-Smtp-Source: ABdhPJymCrPKEJrK9bpTTNL+havfHMNL5yrkFkOZaYz3L9Xiqp71uXX0+wWVEIyXNFT8fde4tosoCw== X-Received: by 2002:a67:eb17:: with SMTP id a23mr8651271vso.56.1634233687121; Thu, 14 Oct 2021 10:48:07 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:06 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 05/21] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Date: Thu, 14 Oct 2021 14:47:36 -0300 Message-Id: <20211014174752.1651347-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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, i686-linux-gnu, and aarch64-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 549bd30c7d..4d6075730f 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -224,6 +224,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 \ @@ -315,6 +316,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 \ @@ -1541,6 +1543,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 9260d2d696..512ed9a9dc 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 4bbf71b587..0fe29e49ee 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1054,6 +1054,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..307cb6fc3b --- /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 *arg) +{ + 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 5b29a4f992..f2cd742e29 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 Thu Oct 14 17:47:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46229 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 2C8FC3858020 for ; Thu, 14 Oct 2021 17:52:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C8FC3858020 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634233968; bh=n3oBPxArtcC3AE7dC1RpoCzTCVHI9g5SKerL93ZNWc4=; 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=YSNtOWypGJxoDNq+uO36I4YZKJI0oCUsFEN6fNmVsycYxZh1FEWE5EH/voi6HP5jF 1PrgqvRVKXoCYJpgoBGIBC9ZbEUAwN7UGl1q+PDMYJaUNKNXVPMHxcPDfgM4QEtngi 8K2lQRcE+OMxedl4GIk/FEhyREdNYPhZGbDgi/5g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x92a.google.com (mail-ua1-x92a.google.com [IPv6:2607:f8b0:4864:20::92a]) by sourceware.org (Postfix) with ESMTPS id 1C8BE3857C47 for ; Thu, 14 Oct 2021 17:48:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1C8BE3857C47 Received: by mail-ua1-x92a.google.com with SMTP id u5so12832216uao.13 for ; Thu, 14 Oct 2021 10:48:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=n3oBPxArtcC3AE7dC1RpoCzTCVHI9g5SKerL93ZNWc4=; b=TQXXvBqJH59WXSWCtnCuFkrVZYfUDFyxitWjXlVFJk0U1vyJrPKalsePpOuiNDAanR h3qZtYbpBcL4yftirgAyYk7c1EDU3i0T2MuOH1GsgiH0fHKRN0FnNN/pKR3DvanXEGf7 LOaamNaCbHuS6gK4zG2Ae+i+JFTACBAJbLEjD/6NNP07c5TJNihmOk9KcFPAuJGxAY8S BTr5DjyLENZVR8cDKW8KmNvRkZsafvQeVsCeZsEc6c66HD1jvmPdQLDSwSrhbZvNLEda 1sul0AN0YqCveRu8ia6qZNeU8mcEP3YGi+p0Ha7qC3V1IYdLojEwID6k2OeLUclvNiuT PPjg== X-Gm-Message-State: AOAM533iYKebFypYTRyEmCmyhx3AHqCPxoNFT33HpiZvnxjyfboDieJX PnVytECV3iMQkaZYbgS5HN2g4AC5Y9ZiTQ== X-Google-Smtp-Source: ABdhPJyXhUOsA4fY5MAtiU+coWE6UoejSE6aNWQCkVNDOQ6EFUJXsSatdTVdfClXK6ygMcSgd1Ptzw== X-Received: by 2002:ab0:4a5e:: with SMTP id r30mr7899955uae.106.1634233688539; Thu, 14 Oct 2021 10:48:08 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:08 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 06/21] elf: Add _dl_audit_objopen Date: Thu, 14 Oct 2021 14:47:37 -0300 Message-Id: <20211014174752.1651347-7-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. --- elf/Makefile | 2 +- elf/dl-audit.c | 42 ++++++++++++++++++++++++++++++++++++++ elf/dl-load.c | 17 +-------------- elf/rtld.c | 23 ++------------------- sysdeps/generic/ldsodefs.h | 5 +++++ 5 files changed, 51 insertions(+), 38 deletions(-) create mode 100644 elf/dl-audit.c diff --git a/elf/Makefile b/elf/Makefile index 4d6075730f..bf18fbc2a4 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -36,7 +36,7 @@ dl-routines = $(addprefix dl-,load lookup object reloc deps \ exception sort-maps lookup-direct \ call-libc-early-init write \ thread_gscope_wait tls_init_tp \ - debug-symbols) + debug-symbols 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 6324fc707c..b5f88e1723 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1518,22 +1518,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 0fe29e49ee..b327097405 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1058,25 +1058,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) @@ -1095,8 +1076,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 9ec1511bb0..12f6346328 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1360,6 +1360,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 a 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 Thu Oct 14 17:47:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46230 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 4DAAF3857C59 for ; Thu, 14 Oct 2021 17:53:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4DAAF3857C59 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234010; bh=i5t+1EEOFBf7bN0NjGbThKfg+d5FC6WIj3cs3oBcl9w=; 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=YPzEGIRkTz27UlPS/wFnGcfhEGaCw86JloLRfnMTXRAPqYC3Wli4hy6iT4oqfPfNc 94O158P9pzfVLM0fCWW354ZAumdNmnk8i6Sp3n0wVpV2HyzHlOa6Z6wdsDPKhrWGfm xFCheuJKxULFEdVgAgL06G8kCuldppY6zFJTpuyg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x929.google.com (mail-ua1-x929.google.com [IPv6:2607:f8b0:4864:20::929]) by sourceware.org (Postfix) with ESMTPS id C02BF3858020 for ; Thu, 14 Oct 2021 17:48:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C02BF3858020 Received: by mail-ua1-x929.google.com with SMTP id i15so13027994uap.0 for ; Thu, 14 Oct 2021 10:48:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=i5t+1EEOFBf7bN0NjGbThKfg+d5FC6WIj3cs3oBcl9w=; b=C6k2ZtMkjm5Ba0pyUcBAQzj0cxXfohIVRGchwijZtzgHWWsM3BESG8aABfTYoaA4sC Z8eUKjEru3zMxv5UnySMV9IgpU3j1fb/ToIz7LQv+yzh8WpI1i6zdHuMgvchxw3HucpL MC2/+WFjNTrEtd8etWvLWhXKeRfDz2m5CvQ2BHn9Q3BxmDV/IwOJzujPBapydj51n/SC 0scJbEzQ4t1P9Os8AStVmMnpt0MQ2oThyxEFQi8oQYJb6xjq4tZA1lqyhDw0Y6YGjxwQ 9Ul9e1+znX7f8UL8q2AeY4qIRqRDWZj8AU9MjkAfd+D/KWzyo2eBdnfGOyRmw71GGl7+ 6DiA== X-Gm-Message-State: AOAM533Q4/v7kL/jMzKoCmlS98K+aCPg/+a6UteUAJ+oC4t8mjG7J3Hn sxWiN/uPaIJ08RtRcqUdacEROFVeIWSKvA== X-Google-Smtp-Source: ABdhPJxMkLFLTgLFXMx708fcc7ZrZzOOg+IqLAm/VYjB3sxrkC01bxWHfvymmKNmi86wWmfn5VctRQ== X-Received: by 2002:a9f:2f17:: with SMTP id x23mr8041314uaj.25.1634233690130; Thu, 14 Oct 2021 10:48:10 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:09 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 07/21] elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid Date: Thu, 14 Oct 2021 14:47:38 -0300 Message-Id: <20211014174752.1651347-8-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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, 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-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 cfe0f1c0c9..6fadf38f7f 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. */ @@ -791,32 +773,14 @@ _dl_close_worker (struct link_map *map, bool force) __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); #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 b5f88e1723..dad7654f94 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1062,28 +1062,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 00f6d8cfcc..4f4d72e325 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -611,25 +611,7 @@ dl_open_worker_begin (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 b327097405..13bb1ba4cd 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1751,18 +1751,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 @@ -2443,23 +2432,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 12f6346328..1237d1a38b 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1361,6 +1361,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 a audit modules. */ From patchwork Thu Oct 14 17:47:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46231 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 5BFF63857C53 for ; Thu, 14 Oct 2021 17:54:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5BFF63857C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234052; bh=jwZs74W/ml2KSrCdz287v9PlPOfGGNn9qVG2gOl3fiE=; 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=VglsaPKnGGei4ADk65Y8+v7+dc99H/EVJKd00t4H959wFnb4MWS0cm5cSbYM1IJCs tSP0EmieCXvDdFREwNtQd8Y+mAJznOph9XOlfYkurq5YP/wvBLXTkQIq4QYpvQe4sf fnmvTG+W1H3Zjwc0b2OIqpv/GgaIUJfGryUL0gFA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x933.google.com (mail-ua1-x933.google.com [IPv6:2607:f8b0:4864:20::933]) by sourceware.org (Postfix) with ESMTPS id 0DD013858025 for ; Thu, 14 Oct 2021 17:48:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0DD013858025 Received: by mail-ua1-x933.google.com with SMTP id f4so12918873uad.4 for ; Thu, 14 Oct 2021 10:48:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jwZs74W/ml2KSrCdz287v9PlPOfGGNn9qVG2gOl3fiE=; b=Kquir0JF6G2zAEi8ba+CWveluRJ0oYYQj69Gc/7nR43YWgmg40ruArhljEndVQMdfm JIfCKUy4XSZ0NgQB3xapqVeHCS/WhKrny4DtBw9/jd9GlJl0vpfiIBelnRr2C8NpTdKS YdBLuifkEQfT7BcZ4CsJn7seCmZJfv0OAZDrKqlMDjiGrKgiFm/na8J1jAU9KlYX9g2m t7ylXiJbYyGvVkmjQDIAmTlLNaj6ozGWJjdBTwWNZw9zKPA8eKDFBwLCzDsUEdpuXsuv kvvFFJ8iM3/Fxx057ql3DFWgOB+0RcLPPZk16FLXDWyPeh7DBGoKzloZhT/ZIt/WaYgz 372A== X-Gm-Message-State: AOAM5333yuaRO54KakIUcM9FgmI22cHUo0YIjT20S1xHGD3qcaYZQGY/ YFM83JFm643sozKVt+YeqkPX1MkF78McPw== X-Google-Smtp-Source: ABdhPJytqkVy62Gz/O+Jg/KDTxHPULHUqmigg5B4BI1g/0Nb5rW36+4vJHB4mkmlTmTmnbI5e4iLpg== X-Received: by 2002:ab0:53c8:: with SMTP id l8mr8016991uaa.26.1634233691543; Thu, 14 Oct 2021 10:48:11 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:11 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 08/21] elf: Add _dl_audit_objsearch Date: Thu, 14 Oct 2021 14:47:39 -0300 Message-Id: <20211014174752.1651347-9-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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, 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-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 dad7654f94..90de8e0061 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1598,33 +1598,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) @@ -2062,36 +2037,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 1237d1a38b..17378339e7 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1361,6 +1361,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 Thu Oct 14 17:47:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46232 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 4F9083857C51 for ; Thu, 14 Oct 2021 17:54:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4F9083857C51 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234094; bh=7PNRPlsQ0+U2r9jZzd7Bg0GC4/FNXvSWiUKNydSXMZ4=; 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=LANRj52BPmIPqUDnQxRerVVm2xhOMQ3bweWtUpaghLj8GymGX7T21Qh5CTtNsmmPg JDqHIAsb4fl0Cy19tLdmhU8HfrCagtTppUpAOsTNRG1eyyQvd+vFASoR+gbC1HFjOh qxPTPFK1YNBOGXGgHWFWjZdpV+CRI8mIeDrtKRAY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x936.google.com (mail-ua1-x936.google.com [IPv6:2607:f8b0:4864:20::936]) by sourceware.org (Postfix) with ESMTPS id 74DD73858025 for ; Thu, 14 Oct 2021 17:48:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 74DD73858025 Received: by mail-ua1-x936.google.com with SMTP id e2so12891301uax.7 for ; Thu, 14 Oct 2021 10:48:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7PNRPlsQ0+U2r9jZzd7Bg0GC4/FNXvSWiUKNydSXMZ4=; b=cWA8sp+32XrBVHjS+wbGKAv18OdEYgiW6S2mYteGeApRF9ThjszIPRAT5lrHvYKKjn OJ9GtRYMiEOwGgJkXpl5EE7Z7kdUq4WKH3pneCURUkvWG2jWCaVRqt5q6Qbe9vBtwyPz y+h1FvNofJ+/N77aiq6NQ239NDwxS6afhXkoYk5aYI2a7p9HaOFlR5R6aSlKWh4PqfsW 3OKMqMdVrp5KTFiIPQ9qwSc3yZgrrncKN4R/H3BU63nymVN8MnifbPUGPWiT8HksRV1z PDQ/BmJcCjo7nyC++v1bZTUWkNEtHTS58C0AkpWSLEmcGyEDpmUkCpsevk8sy1AjzRUi JiUQ== X-Gm-Message-State: AOAM530iJ9dRNBd0BpXjThKcmIyPQI5r3oZLIo+713xeo6JXIxH5Z+pw lcAIsggwwp7g2zeW5mQQJwj334oJNdEMKg== X-Google-Smtp-Source: ABdhPJzFZef4y1lfC2BeQdIuwD2AsL7isMelvG98Wi/3YqQN3BuTg++HjTZS8T9Xt9Z+uhGcegISwQ== X-Received: by 2002:ab0:3a82:: with SMTP id r2mr7897450uaw.101.1634233692940; Thu, 14 Oct 2021 10:48:12 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:12 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 09/21] elf: Add _dl_audit_objclose Date: Thu, 14 Oct 2021 14:47:40 -0300 Message-Id: <20211014174752.1651347-10-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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, 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. --- elf/dl-audit.c | 21 +++++++++++++++++++++ elf/dl-close.c | 20 +------------------- elf/dl-fini.c | 16 +--------------- sysdeps/generic/ldsodefs.h | 1 + 4 files changed, 24 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 6fadf38f7f..cc2c39e927 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 17378339e7..37ec6fa2c5 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1374,6 +1374,7 @@ 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 a audit modules. */ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit); +void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); #endif /* SHARED */ #if PTHREAD_IN_LIBC && defined SHARED From patchwork Thu Oct 14 17:47:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46233 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 4F60F3858004 for ; Thu, 14 Oct 2021 17:55:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4F60F3858004 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234142; bh=lgIp9ftWdxU7uM3CxRSf6iyCpnl+qPOau99p+pKoU6U=; 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=TMXAHHFUFM1+hcmUHteQBIynZzFww0Zql3E6KY2Gay6t93OOQ7HE36EwBDSigGZI5 NZGTBjFWSF+wrr3zDSjKya8gACK4vCTKiEMSWxASeQwjhQoMkOUFIRI/rwjOProAT7 /YzYdW/t6n1JM7Uu6keCa0mQ85eVPnhogUNfAi+I= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x92d.google.com (mail-ua1-x92d.google.com [IPv6:2607:f8b0:4864:20::92d]) by sourceware.org (Postfix) with ESMTPS id 0F5A7385802D for ; Thu, 14 Oct 2021 17:48:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0F5A7385802D Received: by mail-ua1-x92d.google.com with SMTP id h19so12906376uax.5 for ; Thu, 14 Oct 2021 10:48:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lgIp9ftWdxU7uM3CxRSf6iyCpnl+qPOau99p+pKoU6U=; b=i/HfnAwl6fGsXCIrFreGnUyYGj9pz5kKjr1Uo4vCJ5p6717iMsGejRJ/P0H69fGMSd Cwt8hbDhjT7PaiuImskuYyg0dcJP4hd34C87h2priXjb3w9wVvUBM1ISEUq9ReRMFohP DzuLagHxecK68m80abKRuZsojotqFK9neTzfdYbBYyoqDGQ1Odb5cHfmCovYFX/Vq6/+ FI34UnQZ+hHR+qNQFo69762ytiygJG8dpD0W26r96jk1PHrP8BlIPv6hk0HJPFDVuewn zhluNKJL/lrHWb5wlzLyw4gBruRs1wcxDda+r7tQpB8sdTFbHcJGNiP4rbREaBEMbIRE JMwg== X-Gm-Message-State: AOAM533QMFn8cmWfzXJSvzvpt0i1PgtODN2ok56UUlVyKqR3la4EaSh6 ZYIIHCYm4qLpYqWZVYKivmcFEGjV+P5J0g== X-Google-Smtp-Source: ABdhPJy8UQIgWMt3cH7PYBeIJxU7a0PevMDagxCfYsha3kDA3NxnQNYz8yzoNJXSpWDERcJIRbOhoA== X-Received: by 2002:a05:6102:38c6:: with SMTP id k6mr8773850vst.59.1634233694352; Thu, 14 Oct 2021 10:48:14 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:14 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 10/21] elf: Add _dl_audit_symbind_alt and _dl_audit_symbind Date: Thu, 14 Oct 2021 14:47:41 -0300 Message-Id: <20211014174752.1651347-11-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-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 | 6 ++ 5 files changed, 130 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 b0c788eb22..bfbe8f4be4 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -44,83 +44,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 37ec6fa2c5..8cca508080 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1375,6 +1375,12 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action); if main mapping of the namespace is a audit modules. */ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit); void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); +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); +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 Thu Oct 14 17:47:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46234 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 161083857C53 for ; Thu, 14 Oct 2021 17:56:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 161083857C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234184; bh=2mMzl8cveNRt16sLgjf6CKM0djukTHmlXDgrcj18w+4=; 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=tOroKE0eg/3QoDa4Tv6Yo+BWs2jj16JVAZhIeWa/DD0J2fxjTWcnjTu7dBb+DjaPQ Gehj+lBrgEWOxqHMbPVkTbdyGWEoZ9syypUEK4tq/Cvm8ZvOq5m1+OUayurZWTuiLK R4yvNBN52edWdL+0euIvhRT3XA5rR5d+IXByHZcs= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa2b.google.com (mail-vk1-xa2b.google.com [IPv6:2607:f8b0:4864:20::a2b]) by sourceware.org (Postfix) with ESMTPS id 4BDA0385800B for ; Thu, 14 Oct 2021 17:48:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4BDA0385800B Received: by mail-vk1-xa2b.google.com with SMTP id l20so1127079vkm.8 for ; Thu, 14 Oct 2021 10:48:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2mMzl8cveNRt16sLgjf6CKM0djukTHmlXDgrcj18w+4=; b=kCJCawgqKwfnzw47OxFsceuC0e4h7WkN1eQjjzQYIG8eiPxWa9mIuZ5YluLTTSe3Uf 4K75c6rVjpP8OPVObgP/D7YWl+MMQIdmI0a9Izcp8GdQVuRIhe1wXVb3vtx+XFh2Ql9z KUqawhZQCA/LtLZhjEEgAwYs8eRRRymq77C00W0Ea7plDEIL3dDvbBCfWb2cJMA5fpi0 Y8lGHhUQXwDjt/bvOezdDK/6I4OJc0Cjp1hx2r3CkkrkuEpgvjGWW5xAf53k5dPBsy01 6YA34HlC8hQnG44XltYo+AnHoZ3tsnSVNdMivYKC4QZe0xVsLV5psl28hqH36IcDbAtL MT0g== X-Gm-Message-State: AOAM533Yi87GP1CpLuZ784c8L19t/vuiD+5G8JLUj2NNqf3Buj7FWJMA UHYnzG/ElcbwiROTBzwkEyZ9bHbd7giibA== X-Google-Smtp-Source: ABdhPJyOLAKeDa4st4eISGVPi+Kou7dFYth7H+d8/MMGrws2xNjyLNzt5HFTuUCjfhPknNyFLqPhUQ== X-Received: by 2002:a1f:a00e:: with SMTP id j14mr7798987vke.20.1634233695772; Thu, 14 Oct 2021 10:48:15 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:15 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 11/21] elf: Add _dl_audit_preinit Date: Thu, 14 Oct 2021 14:47:42 -0300 Message-Id: <20211014174752.1651347-12-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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, 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. --- csu/libc-start.c | 23 +++-------------------- elf/Versions | 2 +- elf/dl-audit.c | 15 +++++++++++++++ sysdeps/generic/ldsodefs.h | 1 + 4 files changed, 20 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 8cca508080..c69c54200f 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1375,6 +1375,7 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action); if main mapping of the namespace is a audit modules. */ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid, bool check_audit); void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); +void _dl_audit_preinit (struct link_map *l); 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); From patchwork Thu Oct 14 17:47:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46235 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 2FF453857C53 for ; Thu, 14 Oct 2021 17:57:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2FF453857C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234226; bh=Kr/LUSUTQxbgHgE5paHs9QZ3UrCOgsALkVjIyJYsXh4=; 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=peKsrMOPIDkT710iP/2feQiMwNdyzihWEub/15VAkNSw1h5/U+FEcgPVL5sCj8K3I qPfSaF5AK/cCNEQBDaqum1K7lLO/Vf+TKZ5uH0yYlEzFHo5YY+2AE6/IJKXw4wHrxV RFX+4KBlkafc4GhftDtboRaKcaPyNaVV006mT1Fk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa2d.google.com (mail-vk1-xa2d.google.com [IPv6:2607:f8b0:4864:20::a2d]) by sourceware.org (Postfix) with ESMTPS id CB5183858419 for ; Thu, 14 Oct 2021 17:48:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CB5183858419 Received: by mail-vk1-xa2d.google.com with SMTP id z202so3892943vkd.1 for ; Thu, 14 Oct 2021 10:48:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Kr/LUSUTQxbgHgE5paHs9QZ3UrCOgsALkVjIyJYsXh4=; b=0FGKbYu7hRl8cZ0bvKnC6QAWJAHNcPYXHdg7gWvZEJnP5iEa/7Uas4ph7WkB9m9xu2 f9fVgKFT6Ez1qBEeJuR4Pe5BCk90FXDHHvntGoP4egU1Gic3jY4LgjeZNN7dsM9Sostc 721sLk9RAzQtSu88GP4iSyoika+rhAYNf9WiDXJ9ZVTlN0K84NGlSKDM8gAyEOh8lGVh slgtpMtgJLqI+KxVcxp7+zWWnM5rVaVMUiAJSy4TFh4/umF22EEqfTuCP3zgFnS0E0Hi 8uFJ+UOiWR0N3QWMSxTOGufBkRxxysY/jBliA9gWmKHFgjL7V1R5M3gJiDYE4jKr/Rep lCLQ== X-Gm-Message-State: AOAM532WP7SYeJdLRPaZzf//nylY1DSkknmPhYsvQioJ6xPYp4/7V85I 7joQtAiQwo3GdZd3BwsSM9c0sNMYolA= X-Google-Smtp-Source: ABdhPJwa09i31wiJWH81EjspirUK1pCj65UrP7sMChSb42+kJ9aym/Bk36Lll8MOaVgcfZIf5C9J7A== X-Received: by 2002:a1f:2f8d:: with SMTP id v135mr7578433vkv.18.1634233697216; Thu, 14 Oct 2021 10:48:17 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:17 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 12/21] elf: Add _dl_audit_pltenter Date: Thu, 14 Oct 2021 14:47:43 -0300 Message-Id: <20211014174752.1651347-13-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. --- elf/dl-audit.c | 77 ++++++++++++++++++++++++++++++++++++++ elf/dl-runtime.c | 73 +----------------------------------- sysdeps/generic/ldsodefs.h | 3 ++ 3 files changed, 81 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 bfbe8f4be4..c3fc6777ff 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -352,78 +352,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 c69c54200f..39762e1db3 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1382,6 +1382,9 @@ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, 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) +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 Thu Oct 14 17:47:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46236 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 938A23857C53 for ; Thu, 14 Oct 2021 17:57:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 938A23857C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234273; bh=SYgOx2DrleK387Kk77IwhDj6+43uqGTZi5zUr7R5P/M=; 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=IWQ+pdHXvQexiqhFDT9Rhuw5QO2AuazCCbVkOBfCs7POpYAGdAIQ26BOTiQ8DkPK2 uZcG+V9oeua5zIphPPxAey21CfRqsaAGBd4/0zUKLd+SHVW/xnB5F7G/Y1eiB567/S AInAZr5lUgvHFItEHfl/cMJSWiNnXOjbBhPKfBi0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x932.google.com (mail-ua1-x932.google.com [IPv6:2607:f8b0:4864:20::932]) by sourceware.org (Postfix) with ESMTPS id 8CECF3857C47 for ; Thu, 14 Oct 2021 17:48:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8CECF3857C47 Received: by mail-ua1-x932.google.com with SMTP id r17so12885468uaf.8 for ; Thu, 14 Oct 2021 10:48:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SYgOx2DrleK387Kk77IwhDj6+43uqGTZi5zUr7R5P/M=; b=joPuZhwog9OVNdpZEUx9EFGXvp1/ZdfomFbwDQAgXRjFglKBfUseAY8w7W0WAfi33q 9mCwO+HqJeGRuKiab5sipyfiY5DXhnHev70l8gNlxA53BSzPTgsQysDDdwgb4flYye23 qzp9l9ZewSxHQ+PXnUQ2yucws1kIHADbRQhTCBgYYlmnLHYt3U2jmXndsNrE30IPtkwn 6iOGdCtpHlSrDaGiBFmRcKw/SwOY5TUrpTz3iYTsQhWI29pnD+HQnRpIrE2AbchL1iAR 8FGchPSRPKHUbIOXQQScN6z/4j+egReCLF5xh83Z8fx6MLR1Q7Bjt3jIZGrrQw517oIc IGuA== X-Gm-Message-State: AOAM530C5SRzACJUJkr/oow14LRaT+88PUZKZWrvFuI0Bgbbza6ZBiZO M3vxsL1PVPQaZRDYdz2vjXDm9nfRNpaAcA== X-Google-Smtp-Source: ABdhPJxD+r5vP2q+8/bjAvVditYYMsUBkhdv+mhWrPpWeCr+0j/dmDeofqRzPfr4v5JzHKK9Vd8oaA== X-Received: by 2002:a9f:36f0:: with SMTP id p103mr8200152uap.42.1634233698686; Thu, 14 Oct 2021 10:48:18 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:18 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 13/21] elf: Add _dl_audit_pltexit Date: Thu, 14 Oct 2021 14:47:44 -0300 Message-Id: <20211014174752.1651347-14-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Netto 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. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-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 | 5 ++ 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, 151 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 c3fc6777ff..011e6d645d 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 @@ -38,12 +36,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 @@ -53,7 +45,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, @@ -180,7 +172,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, @@ -364,52 +357,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 39762e1db3..b7d9eeac61 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1385,6 +1386,10 @@ 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); +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 169bed50ff..2f0dbc27a9 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -115,29 +115,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], 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 5669ab18f5..1e555de32e 100644 --- a/sysdeps/i386/dl-trampoline.S +++ b/sysdeps/i386/dl-trampoline.S @@ -252,7 +252,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 dfbfefbd4a..812f67f23d 100644 --- a/sysdeps/x86_64/dl-trampoline.h +++ b/sysdeps/x86_64/dl-trampoline.h @@ -357,7 +357,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 @@ -403,7 +403,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 @@ -448,7 +448,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 Thu Oct 14 17:47:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46237 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 AF1593857C52 for ; Thu, 14 Oct 2021 17:58:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AF1593857C52 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234315; bh=TuWdNtVgNYJ2UHiGm8E10XhjCUPgUdCcGfxuSYYZynA=; 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=GoRLnFIQstxFsQYwOZ5AbDb0OAz85NHTR0NzeINmQPKw62DOO6efCO0de75nnyNPa MBkhYFGU4o2aOHGHy3OZdpNtDWAmiwve5JvQhrLit0gbD1g2UH3ti3LXCMikGpJ+G6 UUA/Z2umglEbVqb2M6aPouCXz7Qb/e9q+ZXJp9fo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x930.google.com (mail-ua1-x930.google.com [IPv6:2607:f8b0:4864:20::930]) by sourceware.org (Postfix) with ESMTPS id BD2EF385802D for ; Thu, 14 Oct 2021 17:48:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BD2EF385802D Received: by mail-ua1-x930.google.com with SMTP id i15so13028969uap.0 for ; Thu, 14 Oct 2021 10:48:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TuWdNtVgNYJ2UHiGm8E10XhjCUPgUdCcGfxuSYYZynA=; b=MgwIVl0UsNmJxij1xPXmYDV6aexKabMObeuDuZHo5At4vgcufk/ecMefbYEerBwiKw DQPq/sa9qzLL6PZa4wZgW132fx+LTe9ZWFAhCNstbCfJSHnJyAS5FHIivHap3TfivXmk 4NbDnnP7+On2dKjgReBRHz9E1xqocCGSaTBL3JaVH9iMsx1q9NSslUmRXJyJevoGf0b9 JTIUyr1l4T6pXMBBKwB4O379/dddCE8O9VqenhzWrbApbCej8eNlT5vVxUa+VT0n+GWp XPkyLa1x08oTPzHErcJmpdZlLDEMjJZZ94Nkea5zumBcUnBrdYAenwAnRs87w7Fe9FVq NoFg== X-Gm-Message-State: AOAM533UgdADALwcWLWT8kQTQo7FQCcRyReS3sghjxJ/oaCM+Yg9TRpa AMfENUMmw4a2QJFAAjUVltXZkBgy7ksh9w== X-Google-Smtp-Source: ABdhPJwHRk8ziyMxwGiovYD3VF5lvyWznVqRQi8OzqdAnBulCS2FVTg2NB7ITeV7Bx2KjLsn1/UU+g== X-Received: by 2002:a67:ee88:: with SMTP id n8mr8400521vsp.58.1634233700047; Thu, 14 Oct 2021 10:48:20 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:19 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 14/21] elf: Issue audit la_objopen() for vDSO Date: Thu, 14 Oct 2021 14:47:45 -0300 Message-Id: <20211014174752.1651347-15-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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, i686-linux-gnu, and aarch64-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 bf18fbc2a4..3c3f5cd37a 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 \ @@ -317,6 +318,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 \ @@ -1546,6 +1548,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 13bb1ba4cd..7f559b1aa7 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1875,6 +1875,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 f44748bc98..9e5410d613 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)) { l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso) 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 Thu Oct 14 17:47:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46238 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 CE8703858015 for ; Thu, 14 Oct 2021 17:59:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CE8703858015 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234363; bh=FilIzGk9l/X2Djq3lJXR0xf/6u/GYQbYTqZEjkWE/rk=; 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=li6vx7pBa3Xw/Nxw8hcIp8e401Kr3cpw6nWElMfcEPxHCRQJI1qIWvkXR8SOQVkFm 3r0q9/THQCX/7X2k9nWlv0hCJlWPTIYq+LLvUcff30fz/7uh4x5Biw3WMkgq4xbR5z OFXamzgYyDvaUW8MHLAhBgY2Gttgb0yaMFihLbhc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x92c.google.com (mail-ua1-x92c.google.com [IPv6:2607:f8b0:4864:20::92c]) by sourceware.org (Postfix) with ESMTPS id 28BB63857C53 for ; Thu, 14 Oct 2021 17:48:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 28BB63857C53 Received: by mail-ua1-x92c.google.com with SMTP id h4so12976597uaw.1 for ; Thu, 14 Oct 2021 10:48:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FilIzGk9l/X2Djq3lJXR0xf/6u/GYQbYTqZEjkWE/rk=; b=FIV8e82Drnplya01CRgeqr3wYQ3mvG+9kXXbpGwEDPTmDS/TXVUiAUzujoTgiFPGly X7fALaSnkbi3/Zqs01b/vgnNpGCo4qz4nEG3vQwBG9TJbH1221nipK8HSZcRW2zpi9nj nxsn1tsB2wN0mPuIaAkERqyuhbGsNUWMtQ12QJyUjW0ym57gts8IxIaGtVEGTpuPUFkg am5dfIkN16MtYKLq3bYxR1ZUrASv5t7hiP0EOuQn8pY2lotorMef5sZZ/lP3fUZkML9I O6AGTywG+LcGkpUWB/bUxG4PFqoewpxrc/JfhaYRnFXRgFFHBc3StSBrU8AY5fEOpoLd gbQw== X-Gm-Message-State: AOAM531PAnPdUCF5veNHCQ4qILe1oZGC271ZLRabPr3C1vDKNgbld6mm 8t7whEJlOezF0KEGGkLemc30pGsFLdQOiA== X-Google-Smtp-Source: ABdhPJxoljFkCJ5gnAgLBfO9IAtVTMNxpXXETngA2J4cpKuoG1tYQskmUSq9BPsiiwgBm5/EXwAVNw== X-Received: by 2002:ab0:30b3:: with SMTP id b19mr8109422uam.123.1634233701514; Thu, 14 Oct 2021 10:48:21 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:21 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 15/21] elf: Add main application on main_map l_name Date: Thu, 14 Oct 2021 14:47:46 -0300 Message-Id: <20211014174752.1651347-16-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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 90de8e0061..0c7a659c13 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1996,13 +1996,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 7f559b1aa7..404c7ff041 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1360,11 +1360,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 @@ -1427,6 +1422,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 Thu Oct 14 17:47:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46239 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 34A2F385843D for ; Thu, 14 Oct 2021 18:00:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 34A2F385843D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234406; bh=kHsTqi4WO+TT54rcIy/UU1PZHBm+r9tU4a3LYvZOQyM=; 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=uqnNe2FjpAxEwsa8xrSWnTOpVnLZlfuQuEzVlXRBoEsrMKE5KgcX9+VUpd4n8OU81 IBwKrmVMdcqYZVdKfagI31od20tWuVhG900W82s/VWMO7/tE96Q91i3w6fru48fjAl YIUAbNDyl0HjOH6vNf/uNiwuy+8I2jRY9BzIXHh4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x933.google.com (mail-ua1-x933.google.com [IPv6:2607:f8b0:4864:20::933]) by sourceware.org (Postfix) with ESMTPS id 94F593857C59 for ; Thu, 14 Oct 2021 17:48:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 94F593857C59 Received: by mail-ua1-x933.google.com with SMTP id j8so12882174uak.9 for ; Thu, 14 Oct 2021 10:48:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kHsTqi4WO+TT54rcIy/UU1PZHBm+r9tU4a3LYvZOQyM=; b=63lhX3c3d4yp8I/IIXnJCwovLVUWBzMj/GnyQy12XgAwV8a2vWybzPz6O9Mg7OBtVM OFwLoqgKKPruVPq1RHg+SJJAXuFcuk9Q8VSWFD7/tIQJwjHfyF7541hxgUlPBDddPRPx sf9BpuCV8vmB685+K3wmern8hNeFLnmF8PgMx9cUOJlMfAYXfNwwXn4Zd6JslTxCePrZ N5dU6/Y9bekMABWJSQbt7fWrpuu8E8p9zsKLHSqEIaPofYrTzyIbeiQ6idpIXwdXJ5uV D4qMoVbYf3SBTcTKIE+Z7i7I1vX+RVuqG62jTrlKCd47ZJQxhd5P0ko7aA0JtsG3Pmvz +5uw== X-Gm-Message-State: AOAM532gtrP32bxJjzIk+FJf48EBMl0SCQjPf9dR2EeVfbEvTFNAryla EhtVWCzWvW7RoDPUo0x4cOQ8Lci7W8QZUQ== X-Google-Smtp-Source: ABdhPJzSPYB1OJbFzxZF8EOd6PC9SDGoKMrLSsTFuNts7jNa7BYrbYxdCGHHtOr8YUslLrb2UB90dA== X-Received: by 2002:ab0:5b59:: with SMTP id v25mr7873107uae.57.1634233702926; Thu, 14 Oct 2021 10:48:22 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:22 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 16/21] elf: Add la_activity during application exit Date: Thu, 14 Oct 2021 14:47:47 -0300 Message-Id: <20211014174752.1651347-17-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Netto 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, i686-linux-gnu, and aarch64-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 3c3f5cd37a..7cd3325795 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 \ @@ -319,6 +320,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 \ @@ -1551,6 +1553,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 Thu Oct 14 17:47:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46242 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 599F13857C53 for ; Thu, 14 Oct 2021 18:02:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 599F13857C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234539; bh=cTTXTT6tjUk5cZ+yOI4we4xWWs3AA/iLsMfiZNlggFU=; 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=Gs4rUqhVTg5rNy5fKGKf+a+c+t7JNrpvVTHdxEy6xCvTeHeN41+g1Ag27nI2vspZ+ jJGpb1Eb5SfE5GwJxR5j1v1w3BnMKnEaTaIL2vhId5MNT4m2to6Jx5zyKa23c9S+Bp alQvi625syNG7XimHPv8QG+OkUfNGcvMR+GtPRBY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x936.google.com (mail-ua1-x936.google.com [IPv6:2607:f8b0:4864:20::936]) by sourceware.org (Postfix) with ESMTPS id D24293858007 for ; Thu, 14 Oct 2021 17:48:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D24293858007 Received: by mail-ua1-x936.google.com with SMTP id f4so12920189uad.4 for ; Thu, 14 Oct 2021 10:48:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cTTXTT6tjUk5cZ+yOI4we4xWWs3AA/iLsMfiZNlggFU=; b=pcOb9cCsNZYBAzQiYsLOXvNM/Vke1Y5fuxRiqa+zacEt9OuHwb/O4mhOHCV6tdh5bG PPfc3FEEJeR6kyPkHEX0fO3+Wq0X5oe3nid+eKPqUUJbVLkc8vgxF8pPr18fi/XW/7jP sO2XJlwWOr0iCjBiT5wa7MzqfKl2fUczFk48O3QWHQ/EsfAgNfglMt8oAOF1kjbUjWjK b3Dg78zdzJlJRQ9d6X5lPw9eW+ZDe56TyzecnvinqUE8VmSBXdjfJkErUxBQ28XJqECS +NdwISrZezTEnOMfEldia4Z7CQJk+q+tFJVrQS1xptQBU8vVefMu9TT5AKe8U4T2miAB Bn2g== X-Gm-Message-State: AOAM532pQ/DFdfOxwMccYyPXq1hRgfhJA2avZNJK/0lGjPCHRy4nzxz6 axT0EDlMBvNmhnXa62A2bMcbkLA8Ksk= X-Google-Smtp-Source: ABdhPJznWD6oGBpdo8kM+pxmzs4EE7eHctmBlTkueH7wLXEYhKDVi9kDy+KCJ05Bd0GVkl6U2+NRFA== X-Received: by 2002:a67:d583:: with SMTP id m3mr8802862vsj.41.1634233704496; Thu, 14 Oct 2021 10:48:24 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:24 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 17/21] elf: Issue la_symbind() for bind-now (BZ #23734) Date: Thu, 14 Oct 2021 14:47:48 -0300 Message-Id: <20211014174752.1651347-18-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 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, 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 Netto 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). To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind() requires to know whether bind-now is used so the symbol value is updated to function text segment instead of the ODP (for lazy binding this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve). Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, powerpc64-linux-gnu. --- elf/Makefile | 50 +++++++++++++++ elf/dl-audit.c | 5 +- elf/dl-reloc.c | 8 +-- elf/dl-runtime.c | 4 +- elf/do-rel.h | 65 +++++++++++++++---- 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 +++++++++++++++++++++++++++++++++ sysdeps/generic/dl-lookupcfg.h | 1 + sysdeps/generic/ldsodefs.h | 2 +- sysdeps/powerpc/dl-lookupcfg.h | 30 +++++++++ 25 files changed, 821 insertions(+), 24 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 create mode 100644 sysdeps/powerpc/dl-lookupcfg.h diff --git a/elf/Makefile b/elf/Makefile index 7cd3325795..250fc72460 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 \ @@ -321,6 +322,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 \ @@ -1557,6 +1563,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-audit.c b/elf/dl-audit.c index c3569cb357..4540d93913 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 @@ -238,7 +238,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, if (new_value != (uintptr_t) sym.st_value) { flags |= LA_SYMB_ALTVALUE; - sym.st_value = new_value; + sym.st_value = bindnow + ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value; } } diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 27f792b7b2..6a53f57146 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -232,9 +232,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)) @@ -283,8 +281,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], { /* Do the actual relocation of the object's GOT and other data. */ - ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); - #ifndef PROF if (consider_profiling | consider_symbind && l->l_info[DT_PLTRELSZ] != NULL) @@ -307,6 +303,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], } } #endif + + ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); } /* Mark the object so we know this work has been done. */ diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 011e6d645d..666256a215 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -147,7 +147,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))) @@ -322,7 +322,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 f441b74919..c3368f09ab 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, struct r_scope_elem *scope[], 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) { @@ -133,10 +142,20 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], } #endif - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; - elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], - &map->l_versions[ndx], - (void *) (l_addr + r->r_offset), skip_ifunc); + elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, + skip_ifunc); +#if defined SHARED && !defined RTLD_BOOTSTRAP + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT + && map->l_reloc_result != NULL) + { + struct link_map *sym_map + = RESOLVE_MAP (map, scope, &sym, rversion, + ELF_MACHINE_JMP_SLOT); + if (sym != NULL) + _dl_audit_symbind (map, &map->l_reloc_result[ri++], sym, + r_addr_arg, sym_map, true); + } +#endif } #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP @@ -157,18 +176,38 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], #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, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, - (void *) (l_addr + r->r_offset), skip_ifunc); + elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg, + skip_ifunc); +# if defined SHARED && !defined RTLD_BOOTSTRAP + if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT + && map->l_reloc_result != NULL) + { + struct link_map *sym_map + = RESOLVE_MAP (map, scope, &sym, + (struct r_found_version *) NULL, + ELF_MACHINE_JMP_SLOT); + if (sym != NULL) + _dl_audit_symbind (map, &map->l_reloc_result[ri++], sym, + r_addr_arg, sym_map, true); + } +# 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 (); +} diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h index c038c31ce6..4ab6187372 100644 --- a/sysdeps/generic/dl-lookupcfg.h +++ b/sysdeps/generic/dl-lookupcfg.h @@ -26,3 +26,4 @@ #define DL_FIXUP_VALUE_CODE_ADDR(value) (value) #define DL_FIXUP_VALUE_ADDR(value) (value) #define DL_FIXUP_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index b7d9eeac61..2d36abc173 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1379,7 +1379,7 @@ void _dl_audit_objclose (struct link_map *l, Lmid_t nsid); void _dl_audit_preinit (struct link_map *l); 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); 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) diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h new file mode 100644 index 0000000000..96f5b50e81 --- /dev/null +++ b/sysdeps/powerpc/dl-lookupcfg.h @@ -0,0 +1,30 @@ +/* Configuration of lookup functions. PowerPC version. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define DL_FIXUP_VALUE_TYPE ElfW(Addr) +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) +#define DL_FIXUP_VALUE_ADDR(value) (value) +#define DL_FIXUP_ADDR_VALUE(addr) (addr) +#if __WORDSIZE == 64 && _CALL_ELF == 1 +/* We need to correctly set the audit modules value for bind-now. */ +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \ + (((Elf64_FuncDesc *)(addr))->fd_func) +#else +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#endif From patchwork Thu Oct 14 17:47:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46241 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 194443858427 for ; Thu, 14 Oct 2021 18:01:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 194443858427 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234496; bh=5epR9JAcqUe6pyByz+rHxphYx/AjH9h00cSN+IuZS5Q=; 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=iOLS5kurE60EybeXozLC1p8KHRx0SrPbtNLNobAdceewf8Ws3YKWuYgKpoP8ZRGFO EeHkoQZhr9yOaU6tumiq8HnKhbM6bHm1fcBlMcyNecJsJOyqB/yEXzkho9a/38sAC9 tWFPiYgZZUQGs53grKN97eR7TUq6NvMqa8s8bTlU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x934.google.com (mail-ua1-x934.google.com [IPv6:2607:f8b0:4864:20::934]) by sourceware.org (Postfix) with ESMTPS id C878D3857C53 for ; Thu, 14 Oct 2021 17:48:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C878D3857C53 Received: by mail-ua1-x934.google.com with SMTP id a17so3891065uax.12 for ; Thu, 14 Oct 2021 10:48:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5epR9JAcqUe6pyByz+rHxphYx/AjH9h00cSN+IuZS5Q=; b=cIZsEX/iZuPgFUP35Zv7S7tdi2238Ls5P2ROlcHhAouwly04sfY0aymcURSL9ni36O +cNYewZylf3bjCE/uXzrT687VKi6fM8/jLrou8861tsLPn0fLTtMmplWa0H1EJt285Hh HfHlVS4qX6zZzZcrzsAntYbaNFKA0+lb1aR7t1muPdhfKihjo72K3hX6HgGjgfoWfLSU Wj0f++WSSvr9h8sHOykvaFv444v38/wrWHfrnUlMk/v6iezHXi2xocYxaKZ3qC0iMhgN qsrTIRmvnzGzCIIw+k1zphnEEpPyquVCzEqBwOIS3rRbBDwexpSJumfCPs2T7NyJQqcD TTZg== X-Gm-Message-State: AOAM532/6tQKoXLnpDxQyQjjhman4KmtwKYc0qi9IGrr7s/WO1Ec6fow BpP/dlpvgFnf3ebMJCOfUvhA5ouBcjuqeQ== X-Google-Smtp-Source: ABdhPJxQ8PtktZsIjKORhCE0SXtfmcxA9P60GaMM21oO5zWI5sDQCHsohXgDa3YNwF5jrtIqfYUNZw== X-Received: by 2002:ab0:6dcd:: with SMTP id r13mr7884231uaf.74.1634233705907; Thu, 14 Oct 2021 10:48:25 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:25 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 18/21] elf: Add LA_SYMB_BINDNOW Date: Thu, 14 Oct 2021 14:47:49 -0300 Message-Id: <20211014174752.1651347-19-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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, i686-linux-gnu, and aarch64-linux-gnu. --- elf/Makefile | 22 ++++++++ elf/dl-audit.c | 2 +- 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 +++++++++++++++++++++++++ 10 files changed, 461 insertions(+), 2 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 250fc72460..4ee07d2115 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 \ @@ -327,6 +328,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 \ @@ -1607,6 +1610,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 4540d93913..09243a0aa3 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -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/link.h b/elf/link.h index 200d40c9c6..67ab2495cc 100644 --- a/elf/link.h +++ b/elf/link.h @@ -148,8 +148,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; +} From patchwork Thu Oct 14 17:47:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46240 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 7E6793857C52 for ; Thu, 14 Oct 2021 18:00:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7E6793857C52 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234448; bh=/KQGBXoCX3Wcxv+4n9aDW1Y/dTSlylnOHLi1efExNUM=; 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=eKKPly1Vuxz7ceStN+BjhtWjfm2+1jvmOuaqC9vfwxPs1N+NhNIwz6GkitAr8vERV f0zrrMJcBCVXX88QYaoP18CBhcIAL7+mkgw9c1GG0pAKRmuScdqIAPBYxKfs0gK7S6 STe1h8xlRQgPKuT+kYnBEQmcRafkcHKOglOhl3GQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x92b.google.com (mail-ua1-x92b.google.com [IPv6:2607:f8b0:4864:20::92b]) by sourceware.org (Postfix) with ESMTPS id 011203857C42 for ; Thu, 14 Oct 2021 17:48:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 011203857C42 Received: by mail-ua1-x92b.google.com with SMTP id f4so12920361uad.4 for ; Thu, 14 Oct 2021 10:48:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/KQGBXoCX3Wcxv+4n9aDW1Y/dTSlylnOHLi1efExNUM=; b=USOM6VGgXvrpy9okBTdE2NNeWcz61i8qGWua0jVLKoxwAh6Nm1fn2JjQSFDxj/zj5A looWrpCpbS31t+eBok7FDnrn/A77mxkcxt3vf6/1JUg0JygJ+WwXI1h5oczlWyswsMr0 87Ui6oZntASwGzOJ7Q5tKl0bTdoOZbPVL2K27WnCTjzKZPQ2r5PZo3k25brcQzZvG6sR fjJ/alUvjMZvCyBsfs9MARmpNUvt3rJT3TLKhNqVMMteQx9yV+WFYePI2bn4qimk0vzO tmDhXWUB7Gtoqk4q0LOtWuidICAm8up5HxDuEHQJMxMHTNTo7OMvniTyZyYLn1baoPuj V3Zg== X-Gm-Message-State: AOAM533VkRArIutDk/iTT4RBTcqfi+eepekr5I4+Xe84ykriguo6UGMS fVOtFUvkcpftvOm685qhogZnyBWQOJdFVg== X-Google-Smtp-Source: ABdhPJxuDzYGgMTjm9biTkn96sPm6emPOfCyMIl/FQFvK1sbjE1pQ4lO+AXu3O1/IfdIa1ELgwWIVA== X-Received: by 2002:ab0:5a93:: with SMTP id w19mr7978015uae.58.1634233707448; Thu, 14 Oct 2021 10:48:27 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:27 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 19/21] elf: Move LAV_CURRENT to link_lavcurrent.h Date: Thu, 14 Oct 2021 14:47:50 -0300 Message-Id: <20211014174752.1651347-20-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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 4ee07d2115..2c4496a633 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 67ab2495cc..debbcd2fcb 100644 --- a/elf/link.h +++ b/elf/link.h @@ -113,7 +113,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 Thu Oct 14 17:47:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46243 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 9B8AB3858427 for ; Thu, 14 Oct 2021 18:03:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B8AB3858427 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234589; bh=aEvfQampGcsJU/iBhQQoF1HA3kO77bpEknnp1dzFtH8=; 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=Hu3CBJEvMmrvJdOy7fMtWDQBSRzeOyrpUn9PFTqNt+cPFWzFpH+HWcVRB0VoNk0IT UoOHLLfAB6dFj4zcqmAgP89x7Wxdh6Tnnz3+S42DFP7zfpZwDRlFK+aveLVAZufy/N PoNAKeu/9gaqapstRE+2EiZ2ep5DoRLortPEO9Eg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x92d.google.com (mail-ua1-x92d.google.com [IPv6:2607:f8b0:4864:20::92d]) by sourceware.org (Postfix) with ESMTPS id 7956B3857C47 for ; Thu, 14 Oct 2021 17:48:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7956B3857C47 Received: by mail-ua1-x92d.google.com with SMTP id e10so8287544uab.3 for ; Thu, 14 Oct 2021 10:48:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=aEvfQampGcsJU/iBhQQoF1HA3kO77bpEknnp1dzFtH8=; b=mYlPFTSWMGqrGXQKzNvKj9I9j9agJITvczR+Yy8fRCBsJzV9O4NnC4VKvsLXwJlDTR 6+/aeAoyZBOPbMmPqX2/Gwaa8NZTVlkI8SdrzqbI73ncyjmsAlyTKd0lU2mH6N/8btp2 V/iYRWYMBmYSCAIOaqD2xjf3BvhCKX9+JlJxkg2iXkAuBoBZ42UUzhHYpAXKWL8LLmzE 9hdpElNsii5bm0VxhihJST6JQ/H7PkaRMeb7jv/J/c7H0SoZkZSDbgvj0DRftYTc9Dw8 XvrFjgkP/QPEaLBuf0Cj3UZK40BvszONfxJ72pD2kQe4kJvB95h+yLzcap4sblkehWoK U5+w== X-Gm-Message-State: AOAM531W771cjj/S2GynAkaIlDFVEBrELZ9TaXD9YD51yZC9qUCJ0dzN alDsad/mMqcWDV6aRhEOcOPTrNwW78ou+Q== X-Google-Smtp-Source: ABdhPJwnrxFVsTSPVSLhXGT3Bba/WhoIe8CSd+EPtEKfNAl/Lft+9+PTMqo0fNbtWuByOpnl2W9dqA== X-Received: by 2002:ab0:66cd:: with SMTP id d13mr8122621uaq.110.1634233712220; Thu, 14 Oct 2021 10:48:32 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:31 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4 20/21] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Date: Thu, 14 Oct 2021 14:47:51 -0300 Message-Id: <20211014174752.1651347-21-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto 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 has some issues aarch64. with 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 | 93 ++++++++----- 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 | 98 ++++++++++++++ sysdeps/aarch64/tst-auditmod27.c | 175 +++++++++++++++++++++++++ 14 files changed, 741 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 404c7ff041..5cb7b436f5 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -989,10 +989,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..0d540651d4 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,17 @@ _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 + ----------------------- + [sp, #384] La_aarch64_regs::lr_xreg (x0-x8) + [sp, #256] La_aarch64_regs::lr_vreg (q0-q7) + [sp, #240] La_aarch64_regs::sp and La_aarch64_regs::lr + [sp, #176] La_aarch64_retval::lrv_xreg (x0-x7) + [sp, # 48] La_aarch64_retval::lrv_vreg (q0-q7) + [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 */ # define OFFSET_T1 16 @@ -183,19 +188,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 +242,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 +289,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 +311,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..a8e8b28523 --- /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..cbd44c4bdf --- /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..028f638446 --- /dev/null +++ b/sysdeps/aarch64/tst-auditmod26.c @@ -0,0 +1,98 @@ +/* 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 [cookie=%ld]\n", lmid, l_name, ck); + 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"); + + *framesizep = 1024; + + 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_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..b1dbff8330 --- /dev/null +++ b/sysdeps/aarch64/tst-auditmod27.c @@ -0,0 +1,175 @@ +/* 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 [%ld]\n", lmid, l_name, ck); + 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) : "v1"); + asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2"); + asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3"); + asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4"); + asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5"); + asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6"); + asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7"); + + *framesizep = 1024; + + 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].d == 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].q == 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) : "v1"); + asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2"); + asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3"); + asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4"); + asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5"); + asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6"); + asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7"); + + return 0; +} From patchwork Thu Oct 14 17:47:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 46244 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 183FB3857C5B for ; Thu, 14 Oct 2021 18:03:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 183FB3857C5B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634234638; bh=D39nS+S2TkKEYgZrgMnzTXOhpm1OUS2c2E2gXinpTkM=; 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=H1yamhx59wY2babf1rmk5Mlmti/lKB6NH/QJqsvOJptXw4Rwl3jB6aRIuLcKQBWcZ oE3IybSO5t9PtdvTleiGN4xodpkeGHrlBLXBb89GuAAluA5kNxGSaL1S/zGObfnJ2z QDrmb4zNroUJvaNKXDZLgloplWsvdeQLimbsL9WU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x934.google.com (mail-ua1-x934.google.com [IPv6:2607:f8b0:4864:20::934]) by sourceware.org (Postfix) with ESMTPS id 1A4EB3858412 for ; Thu, 14 Oct 2021 17:48:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1A4EB3858412 Received: by mail-ua1-x934.google.com with SMTP id f4so12921051uad.4 for ; Thu, 14 Oct 2021 10:48:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=D39nS+S2TkKEYgZrgMnzTXOhpm1OUS2c2E2gXinpTkM=; b=YhdHZ9uemdwZsy9IwX5qP6y/sTKG5qr+MC5m8augpmKILkrFw/2GVxK7G2GbCmLs8B 21n9BJIECwhTKy60o9himk+XTgOW+sqIB+g024SLuoHmoBFLPvXg2BKS6nnPxWVbbaEK tqtiRASVUU+H/aljwtaPnH5ex+AnWyE+2QNabUXOCwN8NAtIl2LhwTHHWEu97V9C1gEc P+SEa0FFA0ws2oUVZRkFEdtbuilA3VCFRHIWh4cYvwXLIuwKEEcZa/Ua0k/lr0xyYric uwq1yM6wwUUxK21Fb0hhfx/RKiZsrR7ZyWCTLdgI/zcY/RKrllvKRHhvFw8mOLLmfr7y 727g== X-Gm-Message-State: AOAM533Sxi41bq+CgK4a1Cf2P+t4jKvb8cmi4WV7R/vz6iMNZ1akozM2 BC1IK+GH8+MOX/LozInIju2ytBqmi+yrmA== X-Google-Smtp-Source: ABdhPJw7PsHDqzcK2VieZVwD+uVLVy2OOUFQvdmN4MP6hBC25n/QhX9N2Bc1k3hHCQo+V2bFhqN/KA== X-Received: by 2002:a05:6102:1d2:: with SMTP id s18mr8569189vsq.42.1634233713761; Thu, 14 Oct 2021 10:48:33 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:c6c7:3c65:db0e:6fcc:a8e9]) by smtp.gmail.com with ESMTPSA id q26sm2107237vkn.40.2021.10.14.10.48.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 10:48:33 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [RFC 21/21] elf: Add SVE support for aarch64 rtld-audit Date: Thu, 14 Oct 2021 14:47:52 -0300 Message-Id: <20211014174752.1651347-22-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211014174752.1651347-1-adhemerval.zanella@linaro.org> References: <20211014174752.1651347-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 Netto Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" To implement lazy binding is enabled when profiling or auditing used, even when STO_AARCH64_VARIANT_PCS is set. Also, to not incur in performance penalties on architecture without SVE, the PLT entrypoint is set to a newer one, _dl_runtime_profile_sve, which is used iff 'hwcap' has HWCAP_SVE bit set. This should be a fair assumption since SVE has a defined set of registers for argument passing and return values. A new ABI with either different argument passing or different registers would require a different PLT entry, but I assume this would require another symbol flag anyway (or at least a different ELF mark to indicate so). The profile '_dl_runtime_profile_sve' entrypoint assumes the largest SVE register size possible (2048 bits) and thus it requires a quite large stack (8976 bytes). I think it would be possible make the stack requirement dynamic depending of the vector length, but it would make the PLT audit function way more complex. It extends the La_aarch64_vector with a long double pointer to a stack alloced buffer to hold the SVE Z register, along with a pointer to hold the P registers on La_aarch64_regs. It means the if 'lr_sve' is 0 in either La_aarch64_regs or La_aarch64_retval the La_aarch64_vector contains the floating-pointer registers that can be accessed directly (non SVE hardware). Otherwise, 'La_aarch64_vector.z' points to a memory area that holds up to 'lr_sve' bytes for the Z registers, which can be loaded with svld1 intrinsic for instance (as tst-audit28.c does). The P register follows the same logic, with each La_aarch64_regs.lr_sve_pregs pointing to an area of memory 'lr_sve/8' in size. So, to access the FP register as float you can use: static inline float regs_vec_to_float (const La_aarch64_regs *regs, int idx) { float r; if (regs->lr_sve == 0) r = regs->lr_vreg[idx].s; else memcpy (&r, ®s->lr_vreg[idx].z[0], sizeof (r)); return r; } This patch is not complete yet: the tst-audit28 does not check if compiler supports SVE (we would need a configure check to disable for such case), I need to add a proper comment for the _dl_runtime_profile_sve stack layout, the test need to check for the P register state clobbering. I also haven't check the performance penalties with this approach, and maybe the way I am saving/restoring the SVE register might be optimized. In any case, I checked on a SVE machine and at least the testcase work as expected without any regressions. I also did a sniff test on a non SVE machine. Checked on aarch64-linux-gnu with SVE support. TODO: * Check arm_sve.h and avoid building tests if compiler does not support it. * Add P regs tests. --- elf/do-rel.h | 6 +- elf/dynamic-link.h | 30 ++- sysdeps/aarch64/Makefile | 16 +- sysdeps/aarch64/bits/link.h | 4 + sysdeps/aarch64/dl-link.sym | 3 + sysdeps/aarch64/dl-machine.h | 14 +- sysdeps/aarch64/dl-trampoline.S | 296 +++++++++++++++++++++++++ sysdeps/aarch64/tst-audit28.c | 44 ++++ sysdeps/aarch64/tst-audit28mod.c | 48 ++++ sysdeps/aarch64/tst-audit28mod.h | 74 +++++++ sysdeps/aarch64/tst-auditmod27.c | 187 +++++++++++----- sysdeps/aarch64/tst-auditmod28.c | 193 ++++++++++++++++ sysdeps/alpha/dl-machine.h | 2 +- sysdeps/arc/dl-machine.h | 2 +- sysdeps/arm/dl-machine.h | 2 +- sysdeps/csky/dl-machine.h | 2 +- sysdeps/hppa/dl-machine.h | 2 +- sysdeps/i386/dl-machine.h | 2 +- sysdeps/ia64/dl-machine.h | 2 +- sysdeps/m68k/dl-machine.h | 2 +- sysdeps/microblaze/dl-machine.h | 2 +- sysdeps/mips/dl-machine.h | 2 +- sysdeps/nios2/dl-machine.h | 2 +- sysdeps/powerpc/powerpc32/dl-machine.h | 2 +- sysdeps/powerpc/powerpc64/dl-machine.h | 2 +- sysdeps/riscv/dl-machine.h | 2 +- sysdeps/s390/s390-32/dl-machine.h | 2 +- sysdeps/s390/s390-64/dl-machine.h | 2 +- sysdeps/sh/dl-machine.h | 2 +- sysdeps/sparc/sparc32/dl-machine.h | 2 +- sysdeps/sparc/sparc64/dl-machine.h | 2 +- sysdeps/x86_64/dl-machine.h | 2 +- 32 files changed, 862 insertions(+), 93 deletions(-) create mode 100644 sysdeps/aarch64/tst-audit28.c create mode 100644 sysdeps/aarch64/tst-audit28mod.c create mode 100644 sysdeps/aarch64/tst-audit28mod.h create mode 100644 sysdeps/aarch64/tst-auditmod28.c diff --git a/elf/do-rel.h b/elf/do-rel.h index c3368f09ab..8ae7bacebe 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -43,7 +43,7 @@ static inline void __attribute__ ((always_inline)) elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) reladdr, ElfW(Addr) relsize, __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative, - int lazy, int skip_ifunc) + int lazy, int profile, int skip_ifunc) { const ElfW(Rel) *r = (const void *) reladdr; const ElfW(Rel) *end = (const void *) (reladdr + relsize); @@ -70,13 +70,13 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], } else # endif - elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc); + elf_machine_lazy_rel (map, scope, l_addr, r, profile, skip_ifunc); # ifdef ELF_MACHINE_IRELATIVE if (r2 != NULL) for (; r2 <= end2; ++r2) if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) - elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc); + elf_machine_lazy_rel (map, scope, l_addr, r2, profile, skip_ifunc); # endif } else diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index ac4cc70dea..8199b44d6d 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -54,11 +54,13 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, static inline void __attribute__((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + int profile, int skip_ifunc); # else static inline void __attribute__((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + int profile, int skip_ifunc); # endif #endif @@ -84,7 +86,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL* are completely separate and there is a gap between them. */ -# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \ +# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, do_profile, \ + skip_ifunc, test_rel) \ do { \ struct { ElfW(Addr) start, size; \ __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ @@ -123,7 +126,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], \ if (ELF_DURING_STARTUP) \ elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size, \ - ranges[0].nrelative, 0, skip_ifunc); \ + ranges[0].nrelative, 0, 0, skip_ifunc); \ else \ { \ int ranges_index; \ @@ -133,7 +136,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ranges[ranges_index].size, \ ranges[ranges_index].nrelative, \ ranges[ranges_index].lazy, \ - skip_ifunc); \ + do_profile, \ + skip_ifunc); \ } \ } while (0) @@ -145,19 +149,21 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], # if ! ELF_MACHINE_NO_REL # include "do-rel.h" -# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \ - _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) +# define ELF_DYNAMIC_DO_REL(map, scope, lazy, profiling, skip_ifunc) \ + _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, profiling, \ + skip_ifunc, _ELF_CHECK_REL) # else -# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) /* Nothing to do. */ +# define ELF_DYNAMIC_DO_REL(map, scope, lazy, profiling, skip_ifunc) /* Nothing to do. */ # endif # if ! ELF_MACHINE_NO_RELA # define DO_RELA # include "do-rel.h" -# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \ - _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) +# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, profiling, skip_ifunc) \ + _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, profiling, skip_ifunc, \ + _ELF_CHECK_REL) # else -# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */ +# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, profiling, skip_ifunc) /* Nothing to do. */ # endif /* This can't just be an inline function because GCC is too dumb @@ -166,8 +172,10 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], do { \ int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \ (consider_profile)); \ - ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ - ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ + ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, (consider_profile), \ + skip_ifunc); \ + ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, (consider_profile), \ + skip_ifunc); \ } while (0) #endif diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile index 7183895d04..a2c64d7d5d 100644 --- a/sysdeps/aarch64/Makefile +++ b/sysdeps/aarch64/Makefile @@ -12,13 +12,16 @@ ifeq ($(subdir),elf) sysdep-dl-routines += dl-bti tests += tst-audit26 \ - tst-audit27 + tst-audit27 \ + tst-audit28 modules-names += \ tst-audit26mod \ tst-auditmod26 \ tst-audit27mod \ - tst-auditmod27 + tst-auditmod27 \ + tst-audit28mod \ + tst-auditmod28 $(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \ $(objpfx)tst-auditmod26.so @@ -30,6 +33,15 @@ $(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \ $(objpfx)tst-audit27mod.so: $(libsupport) LDFLAGS-tst-audit27 += -Wl,-z,lazy tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so + +$(objpfx)tst-audit28: $(objpfx)tst-audit28mod.so \ + $(objpfx)tst-auditmod28.so +CFLAGS-tst-audit28.c += -march=armv8.2-a+sve +CFLAGS-tst-audit28mod.c += -march=armv8.2-a+sve +CFLAGS-tst-auditmod28.c += -march=armv8.2-a+sve +$(objpfx)tst-audit28mod.so: $(libsupport) +LDFLAGS-tst-audit28 += -Wl,-z,lazy +tst-audit28-ENV = LD_AUDIT=$(objpfx)tst-auditmod28.so endif ifeq ($(subdir),elf) diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h index 2af90ca6be..2ad0f5d500 100644 --- a/sysdeps/aarch64/bits/link.h +++ b/sysdeps/aarch64/bits/link.h @@ -25,6 +25,7 @@ typedef union float s; double d; long double q; + long double *z; } La_aarch64_vector; /* Registers for entry into PLT on AArch64. */ @@ -34,6 +35,8 @@ typedef struct La_aarch64_regs La_aarch64_vector lr_vreg[8]; uint64_t lr_sp; uint64_t lr_lr; + uint8_t lr_sve; + uint16_t *lr_sve_pregs[4]; } La_aarch64_regs; /* Return values for calls from PLT on AArch64. */ @@ -43,6 +46,7 @@ typedef struct La_aarch64_retval uint64_t lrv_xreg[8]; /* Up to eight V registers can be used for a return value. */ La_aarch64_vector lrv_vreg[8]; + uint8_t lrv_sve; } La_aarch64_retval; __BEGIN_DECLS diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym index 70d153a1d5..9bc56b98ec 100644 --- a/sysdeps/aarch64/dl-link.sym +++ b/sysdeps/aarch64/dl-link.sym @@ -10,6 +10,9 @@ DL_OFFSET_RG_X0 offsetof(struct La_aarch64_regs, lr_xreg) 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_RG_SVE offsetof(struct La_aarch64_regs, lr_sve) +DL_OFFSET_RG_SVE_PREGS offsetof(struct La_aarch64_regs, lr_sve_pregs) DL_OFFSET_RV_X0 offsetof(struct La_aarch64_retval, lrv_xreg) DL_OFFSET_RV_V0 offsetof(struct La_aarch64_retval, lrv_vreg) +DL_OFFSET_RV_SVE offsetof(struct La_aarch64_retval, lrv_sve) diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index 0d5ad218c1..a039a0c32c 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -69,6 +69,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], ElfW(Addr) *got; extern void _dl_runtime_resolve (ElfW(Word)); extern void _dl_runtime_profile (ElfW(Word)); +#if HAVE_AARCH64_SVE_ASM + extern void _dl_runtime_profile_sve (ElfW(Word)); +#endif got = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]); if (got[1]) @@ -85,7 +88,12 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], end in this function. */ if ( profile) { - got[2] = (ElfW(Addr)) &_dl_runtime_profile; +#if HAVE_AARCH64_SVE_ASM + if (GLRO(dl_hwcap) & HWCAP_SVE) + got[2] = (ElfW(Addr)) &_dl_runtime_profile_sve; + else +#endif + got[2] = (ElfW(Addr)) &_dl_runtime_profile; if (GLRO(dl_profile) != NULL && _dl_name_match_p (GLRO(dl_profile), l)) @@ -383,6 +391,7 @@ __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + int profile, int skip_ifunc) { ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); @@ -390,7 +399,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], /* Check for unexpected PLT reloc type. */ if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1)) { - if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL)) + if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL) + && profile == 0) { /* Check the symbol table for variant PCS symbols. */ const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S index 0d540651d4..6025de64ee 100644 --- a/sysdeps/aarch64/dl-trampoline.S +++ b/sysdeps/aarch64/dl-trampoline.S @@ -205,6 +205,9 @@ _dl_runtime_profile: 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) + strb wzr, [x29, #OFFSET_RG + DL_OFFSET_RG_SVE] + strb wzr, [x29, #OFFSET_RV + DL_OFFSET_RV_SVE] + add x0, x29, #SF_SIZE + 16 ldr x1, [x29, #OFFSET_LR] stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_SP] @@ -341,3 +344,296 @@ _dl_runtime_profile: .size _dl_runtime_profile, .-_dl_runtime_profile #endif .previous + + +#define HWCAP_SVE 22 +#define ZCR_ELx_LEN_MASK 0x1ff + +#if HAVE_AARCH64_SVE_ASM + .arch armv8.2-a+sve + .globl _dl_runtime_profile_sve + .type _dl_runtime_profile_sve, #function + cfi_startproc + .align 2 +_dl_runtime_profile_sve: +# if HAVE_AARCH64_PAC_RET + PACIASP + cfi_window_save +# else + BTI_C +# endif + /* AArch64 we get called with: + ip0 &PLTGOT[2] + ip1 temp(dl resolver entry point) + [sp, #8] lr + [sp, #0] &PLTGOT[n] + + Stack frame layout: + [sp, #...] lr + [sp, #...] &PLTGOT[n] + ------------------------- + TODO + [sp, # 0] x29, lr <- x29 + */ + +# define OFFSET_SVE_T1 16 +# define OFFSET_SVE_SAVED_CALL_X0 OFFSET_SVE_T1 + 8 +# define OFFSET_SVE_FS OFFSET_SVE_SAVED_CALL_X0 + 16 +# define OFFSET_SVE_RV OFFSET_SVE_FS + 8 +# define OFFSET_SVE_RG OFFSET_SVE_RV + DL_SIZEOF_RV +/* Maximum supported z and pregisters size in bytes. */ +# define SIZEOF_SVE_Z_REG 512 +# define SIZEOF_SVE_P_REG SIZEOF_SVE_Z_REG / 8 +/* z0-z7 for argument passing. */ +# define SIZEOF_SVE_RG_Z 8 * SIZEOF_SVE_Z_REG +/* p0-p3 for argument passing. */ +# define SIZEOF_SVE_RG_P 4 * SIZEOF_SVE_P_REG +/* z0-z7 for function return. */ +# define SIZEOF_SVE_RV_P 8 * SIZEOF_SVE_Z_REG +/* SVE registers contents for La_aarch64_regs.lr_vreg */ +# define OFFSET_SVE_RG_Z OFFSET_SVE_RG + DL_SIZEOF_RG +/* SVE registers contents for La_aarch64.regs.lr_sve_pregs */ +# define OFFSET_SVE_RG_P OFFSET_SVE_RG_Z + SIZEOF_SVE_RG_Z +/* SVE registers contents for La_aarch64_retval.lrv_vreg */ +# define OFFSET_SVE_RV_Z OFFSET_SVE_RG_P + SIZEOF_SVE_RG_P + +# define SF_SVE_SIZE OFFSET_SVE_RV_Z + SIZEOF_SVE_RV_P + +# define OFFSET_SVE_PLTGOTN SF_SVE_SIZE +# define OFFSET_SVE_LR OFFSET_SVE_PLTGOTN + 8 + + .macro save_sve_z_reg zreg idx offset save_addr + .ifc \zreg, z0 + .if \offset < 4096 + add x0, x29, \offset + .else + mov x0, \offset + add x0, x29, x0 + .endif + .else + add x0, x0, SIZEOF_SVE_Z_REG + .endif + str \zreg, [x0, #0] + .if \save_addr == 1 + str x0, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 16*\idx] + .else + str x0, [X29, #OFFSET_RV + DL_OFFSET_RV_V0 + 16*\idx] + .endif + .endm + + .macro save_sve_regs offset save_addr + save_sve_z_reg z0 0 \offset \save_addr + save_sve_z_reg z1 1 \offset \save_addr + save_sve_z_reg z2 2 \offset \save_addr + save_sve_z_reg z3 3 \offset \save_addr + save_sve_z_reg z4 4 \offset \save_addr + save_sve_z_reg z5 5 \offset \save_addr + save_sve_z_reg z6 6 \offset \save_addr + save_sve_z_reg z7 7 \offset \save_addr + .if \save_addr == 1 + add x0, x0, SIZEOF_SVE_P_REG + str p0, [x0, #0] + add x0, x0, SIZEOF_SVE_P_REG + str p1, [x0, #0] + add x0, x0, SIZEOF_SVE_P_REG + str p2, [x0, #0] + add x0, x0, SIZEOF_SVE_P_REG + str p3, [x0, #0] + .endif + .endm + + .macro load_sve_regs offset + .if \offset < 4096 + add x12, x29, \offset + .else + mov x12, \offset + add x12, x29, x12 + .endif + ldr z0, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z1, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z2, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z3, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z4, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z5, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z6, [x12, #0] + add x12, x12, SIZEOF_SVE_Z_REG + ldr z7, [x12, #0] + add x12, x12, SIZEOF_SVE_P_REG + ldr p0, [x12, #0] + add x12, x12, SIZEOF_SVE_P_REG + ldr p1, [x12, #0] + add x12, x12, SIZEOF_SVE_P_REG + ldr p2, [x12, #0] + add x12, x12, SIZEOF_SVE_P_REG + ldr p3, [x12, #0] + .endm + + + /* Save arguments. */ + mov x12, #SF_SVE_SIZE + sub sp, sp, x12 + cfi_adjust_cfa_offset (SF_SVE_SIZE) + stp x29, x30, [SP, #0] + mov x29, sp + cfi_def_cfa_register (x29) + cfi_rel_offset (x29, 0) + cfi_rel_offset (lr, 8) + + stp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0] + cfi_rel_offset (x0, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0 + 0) + cfi_rel_offset (x1, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0 + 8) + stp x2, x3, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1] + cfi_rel_offset (x2, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1 + 0) + cfi_rel_offset (x3, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1 + 8) + stp x4, x5, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2] + cfi_rel_offset (x4, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2 + 0) + cfi_rel_offset (x5, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2 + 8) + stp x6, x7, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3] + cfi_rel_offset (x6, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3 + 0) + cfi_rel_offset (x7, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3 + 8) + str x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4 + 0] + cfi_rel_offset (x8, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4 + 0) + /* Note 8 bytes of padding is in the stack frame for alignment */ + save_sve_regs OFFSET_SVE_RG_Z 1 + + /* Store the vector length on lr_sve */ + mov x0, #0 + addvl x0, x0, #1 + strb w0, [x29, #OFFSET_RG + DL_OFFSET_RG_SVE] + strb w0, [x29, #OFFSET_RV + DL_OFFSET_RV_SVE] + + mov x0, #SF_SVE_SIZE + 16 + add x0, x29, x0 + ldr x1, [x29, #OFFSET_SVE_LR] + stp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_SP] + + /* Get pointer to linker struct. */ + ldr PTR_REG (0), [ip0, #-PTR_SIZE] + + /* Prepare to call _dl_profile_fixup(). */ + ldr x1, [x29, OFFSET_SVE_PLTGOTN] /* Recover &PLTGOT[n] */ + + sub x1, x1, ip0 + add x1, x1, x1, lsl #1 + lsl x1, x1, #3 + sub x1, x1, #(RELA_SIZE<<3) + lsr x1, x1, #3 + + stp x0, x1, [x29, #OFFSET_SVE_SAVED_CALL_X0] + + /* Set up extra args for _dl_profile_fixup */ + ldr x2, [x29, #OFFSET_SVE_LR] /* load saved LR */ + add x3, x29, #OFFSET_SVE_RG /* address of La_aarch64_reg */ + add x4, x29, #OFFSET_SVE_FS /* address of framesize */ + bl _dl_profile_fixup + + ldr ip0l, [x29, #OFFSET_SVE_FS] /* framesize == 0 */ + cmp ip0l, #0 + bge 1f + cfi_remember_state + + /* Save the return. */ + mov ip0, x0 + + /* Get arguments and return address back. */ + ldp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0] + ldp x2, x3, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3] + ldr x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4] + load_sve_regs OFFSET_SVE_RG_Z + + cfi_def_cfa_register (sp) + ldp x29, x30, [x29, #0] + cfi_restore (x29) + cfi_restore (x30) + +# if HAVE_AARCH64_PAC_RET + mov x12, SF_SVE_SIZE + add sp, sp, x12 + cfi_adjust_cfa_offset (-SF_SVE_SIZE) + AUTIASP + cfi_window_save + add sp, sp, 16 + cfi_adjust_cfa_offset (-16) +# else + mov x12, SF_SVE_SIZE + 16 + add sp, sp, x12 + cfi_adjust_cfa_offset (- SF_SVE_SIZE - 16) +# endif + + /* Jump to the newly found address. */ + br ip0 + + cfi_restore_state +1: + /* The new frame size is in ip0. */ + + sub PTR_REG (1), PTR_REG (29), ip0l + and sp, x1, #0xfffffffffffffff0 + + str x0, [x29, #OFFSET_SVE_T1] + + mov x0, sp + mov x1, #SF_SVE_SIZE + 16 + add x1, x29, x1 + mov x2, ip0 + bl memcpy + + ldr ip0, [x29, #OFFSET_SVE_T1] + + /* Call the function. */ + ldp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0] + ldp x2, x3, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3] + ldr x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4] + load_sve_regs OFFSET_SVE_RG_Z + blr ip0 + stp x0, x1, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*0] + stp x2, x3, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*1] + stp x4, x5, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*2] + stp x6, x7, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*3] + str x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4] + save_sve_regs OFFSET_SVE_RV_Z 0 + + /* Setup call to pltexit */ + ldp x0, x1, [x29, #OFFSET_SVE_SAVED_CALL_X0] + add x2, x29, #OFFSET_SVE_RG + add x3, x29, #OFFSET_SVE_RV + bl _dl_audit_pltexit + + ldp x0, x1, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*0] + ldp x2, x3, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*1] + ldp x4, x5, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*2] + ldp x6, x7, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*3] + ldr x8, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*4] + load_sve_regs OFFSET_SVE_RV_Z + + /* LR from within La_aarch64_reg */ + ldr lr, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_LR] + cfi_restore(lr) +# if HAVE_AARCH64_PAC_RET + /* Note: LR restored from La_aarch64_reg has no PAC. */ + cfi_window_save +# endif + mov sp, x29 + cfi_def_cfa_register (sp) + ldr x29, [x29, #0] + cfi_restore(x29) + mov x12, SF_SVE_SIZE + 16 + add sp, sp, x12 + cfi_adjust_cfa_offset (- SF_SVE_SIZE - 16) + + br lr + + cfi_endproc + .size _dl_runtime_profile_sve, .-_dl_runtime_profile_sve + .previous +#endif /* HAVE_AARCH64_SVE_ASM */ diff --git a/sysdeps/aarch64/tst-audit28.c b/sysdeps/aarch64/tst-audit28.c new file mode 100644 index 0000000000..28ffbd141f --- /dev/null +++ b/sysdeps/aarch64/tst-audit28.c @@ -0,0 +1,44 @@ +/* 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 +#include "tst-audit28mod.h" + +int +do_test (void) +{ + unsigned long hwcap = getauxval (AT_HWCAP); + if ((hwcap & HWCAP_SVE) == 0) + FAIL_UNSUPPORTED ("system does not support SVE"); + + { + svint8_t r = tst_audit28_func_sve_args (sve_args_z0 (), sve_args_z1 (), + sve_args_z2 (), sve_args_z3 (), + sve_args_z4 (), sve_args_z5 (), + sve_args_z6 (), sve_args_z7 ()); + if (!svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (), r, sve_ret ()))) + FAIL_EXIT1 ("tst_audit28_func_sve_args(): wrong return value"); + } + + return 0; +} + +#include diff --git a/sysdeps/aarch64/tst-audit28mod.c b/sysdeps/aarch64/tst-audit28mod.c new file mode 100644 index 0000000000..f5e24346b4 --- /dev/null +++ b/sysdeps/aarch64/tst-audit28mod.c @@ -0,0 +1,48 @@ +/* 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 +#include "tst-audit28mod.h" + +svint8_t +tst_audit28_func_sve_args (svint8_t z0, svint16_t z1, svint32_t z2, + svint64_t z3, svuint8_t z4, svuint16_t z5, + svuint32_t z6, svuint64_t z7) +{ + assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (), + z0, sve_args_z0 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_s16 (svptrue_b16 (), + z1, sve_args_z1 ()))); + assert (svptest_any (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (), + z2, sve_args_z2 ()))); + assert (svptest_any (svptrue_b64 (), svcmpeq_s64 (svptrue_b64 (), + z3, sve_args_z3 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_u8 (svptrue_b8 (), + z4, sve_args_z4 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_u16 (svptrue_b16 (), + z5, sve_args_z5 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_u32 (svptrue_b32 (), + z6, sve_args_z6 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_u64 (svptrue_b64 (), + z7, sve_args_z7 ()))); + + return sve_ret (); +} diff --git a/sysdeps/aarch64/tst-audit28mod.h b/sysdeps/aarch64/tst-audit28mod.h new file mode 100644 index 0000000000..55e3cdbbc6 --- /dev/null +++ b/sysdeps/aarch64/tst-audit28mod.h @@ -0,0 +1,74 @@ +/* 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 + +static inline svint8_t sve_args_z0 (void) +{ + return svdup_s8 (INT8_MAX); +} + +static inline svint16_t sve_args_z1 (void) +{ + return svdup_s16 (INT16_MAX); +} + +static inline svint32_t sve_args_z2 (void) +{ + return svdup_s32 (INT32_MAX); +} + +static inline svint64_t sve_args_z3 (void) +{ + return svdup_s64 (INT64_MAX); +} + +static inline svuint8_t sve_args_z4 (void) +{ + return svdup_u8 (UINT8_MAX); +} + +static inline svuint16_t sve_args_z5 (void) +{ + return svdup_u16 (UINT16_MAX); +} + +static inline svuint32_t sve_args_z6 (void) +{ + return svdup_u32 (UINT32_MAX); +} + +static inline svuint64_t sve_args_z7 (void) +{ + return svdup_u64 (UINT64_MAX); +} + +static inline svint8_t sve_ret (void) +{ + return svdup_s8 (INT8_MIN); +} + +#define INT_ARGS_RET 0x21 + +svint8_t tst_audit28_func_sve_args (svint8_t z0, svint16_t z1, svint32_t z2, svint64_t z3, + svuint8_t z4, svuint16_t z5, svuint32_t z6, svuint64_t z7); + +#endif diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c index b1dbff8330..9a6e23d752 100644 --- a/sysdeps/aarch64/tst-auditmod27.c +++ b/sysdeps/aarch64/tst-auditmod27.c @@ -16,18 +16,82 @@ License along with the GNU C Library; if not, see . */ +#include #include #include #include #include #include #include +#include "tst-audit.h" #include "tst-audit27mod.h" #define TEST_NAME "tst-audit27" #define AUDIT27_COOKIE 0 +static inline float regs_vec_to_float (const La_aarch64_regs *regs, int i) +{ + float r; + if (regs->lr_sve == 0) + r = regs->lr_vreg[i].s; + else + memcpy (&r, ®s->lr_vreg[i].z[0], sizeof (r)); + return r; +} + +static inline double regs_vec_to_double (const La_aarch64_regs *regs, int i) +{ + double r; + if (regs->lr_sve == 0) + r = regs->lr_vreg[i].d; + else + memcpy (&r, ®s->lr_vreg[i].z[0], sizeof (r)); + return r; +} + +static inline long double regs_vec_to_ldouble (const La_aarch64_regs *regs, + int i) +{ + long double r; + if (regs->lr_sve == 0) + r = regs->lr_vreg[i].q; + else + memcpy (&r, ®s->lr_vreg[i].z[0], sizeof (r)); + return r; +} + +static inline float ret_vec_to_float (const La_aarch64_retval *regs, int i) +{ + float r; + if (regs->lrv_sve == 0) + r = regs->lrv_vreg[i].s; + else + memcpy (&r, ®s->lrv_vreg[i].z[0], sizeof (r)); + return r; +} + +static inline double ret_vec_to_double (const La_aarch64_retval *regs, int i) +{ + double r; + if (regs->lrv_sve == 0) + r = regs->lrv_vreg[i].d; + else + memcpy (&r, ®s->lrv_vreg[i].z[0], sizeof (r)); + return r; +} + +static inline long double ret_vec_to_ldouble (const La_aarch64_retval *regs, + int i) +{ + long double r; + if (regs->lrv_sve == 0) + r = regs->lrv_vreg[i].q; + else + memcpy (&r, ®s->lrv_vreg[i].z[0], sizeof (r)); + return r; +} + unsigned int la_version (unsigned int v) { @@ -47,6 +111,7 @@ la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) 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, @@ -55,39 +120,43 @@ la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, { printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", symname, (long int) sym->st_value, ndx, *flags); + printf (" regs->lr_sve=%d\n", regs->lr_sve); + if (regs->lr_sve > 0) + for (int i = 0; i < array_length (regs->lr_vreg); i++) + printf (" inregs->lr_vreg[%d]=%p\n", i, regs->lr_vreg[i].z); 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); + assert (regs_vec_to_float (regs, 0) == FUNC_FLOAT_ARG0); + assert (regs_vec_to_float (regs, 1) == FUNC_FLOAT_ARG1); + assert (regs_vec_to_float (regs, 2) == FUNC_FLOAT_ARG2); + assert (regs_vec_to_float (regs, 3) == FUNC_FLOAT_ARG3); + assert (regs_vec_to_float (regs, 4) == FUNC_FLOAT_ARG4); + assert (regs_vec_to_float (regs, 5) == FUNC_FLOAT_ARG5); + assert (regs_vec_to_float (regs, 6) == FUNC_FLOAT_ARG6); + assert (regs_vec_to_float (regs, 7) == 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); + assert (regs_vec_to_double (regs, 0) == FUNC_DOUBLE_ARG0); + assert (regs_vec_to_double (regs, 1) == FUNC_DOUBLE_ARG1); + assert (regs_vec_to_double (regs, 2) == FUNC_DOUBLE_ARG2); + assert (regs_vec_to_double (regs, 3) == FUNC_DOUBLE_ARG3); + assert (regs_vec_to_double (regs, 4) == FUNC_DOUBLE_ARG4); + assert (regs_vec_to_double (regs, 5) == FUNC_DOUBLE_ARG5); + assert (regs_vec_to_double (regs, 6) == FUNC_DOUBLE_ARG6); + assert (regs_vec_to_double (regs, 7) == 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); + assert (regs_vec_to_ldouble (regs, 0) == FUNC_LDOUBLE_ARG0); + assert (regs_vec_to_ldouble (regs, 1) == FUNC_LDOUBLE_ARG1); + assert (regs_vec_to_ldouble (regs, 2) == FUNC_LDOUBLE_ARG2); + assert (regs_vec_to_ldouble (regs, 3) == FUNC_LDOUBLE_ARG3); + assert (regs_vec_to_ldouble (regs, 4) == FUNC_LDOUBLE_ARG4); + assert (regs_vec_to_ldouble (regs, 5) == FUNC_LDOUBLE_ARG5); + assert (regs_vec_to_ldouble (regs, 6) == FUNC_LDOUBLE_ARG6); + assert (regs_vec_to_ldouble (regs, 7) == FUNC_LDOUBLE_ARG7); } else abort (); @@ -117,48 +186,56 @@ la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, { printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n", symname, (long int) sym->st_value, ndx); + printf (" inregs->lr_sve=%d\n", inregs->lr_sve); + if (inregs->lr_sve > 0) + for (int i = 0; i < array_length (inregs->lr_vreg); i++) + printf (" inregs->lr_vreg[%d]=%p\n", i, inregs->lr_vreg[i].z); + printf (" outregs->lr_sve=%d\n", outregs->lrv_sve); + if (outregs->lrv_sve > 0) + for (int i = 0; i < array_length (outregs->lrv_vreg); i++) + printf (" outregs->lr_vreg[%d]=%p\n", i, outregs->lrv_vreg[i].z); 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); + assert (regs_vec_to_float (inregs, 0) == FUNC_FLOAT_ARG0); + assert (regs_vec_to_float (inregs, 1) == FUNC_FLOAT_ARG1); + assert (regs_vec_to_float (inregs, 2) == FUNC_FLOAT_ARG2); + assert (regs_vec_to_float (inregs, 3) == FUNC_FLOAT_ARG3); + assert (regs_vec_to_float (inregs, 4) == FUNC_FLOAT_ARG4); + assert (regs_vec_to_float (inregs, 5) == FUNC_FLOAT_ARG5); + assert (regs_vec_to_float (inregs, 6) == FUNC_FLOAT_ARG6); + assert (regs_vec_to_float (inregs, 7) == FUNC_FLOAT_ARG7); + + assert (ret_vec_to_float (outregs, 0) == 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].d == FUNC_DOUBLE_RET); + assert (regs_vec_to_double (inregs, 0) == FUNC_DOUBLE_ARG0); + assert (regs_vec_to_double (inregs, 1) == FUNC_DOUBLE_ARG1); + assert (regs_vec_to_double (inregs, 2) == FUNC_DOUBLE_ARG2); + assert (regs_vec_to_double (inregs, 3) == FUNC_DOUBLE_ARG3); + assert (regs_vec_to_double (inregs, 4) == FUNC_DOUBLE_ARG4); + assert (regs_vec_to_double (inregs, 5) == FUNC_DOUBLE_ARG5); + assert (regs_vec_to_double (inregs, 6) == FUNC_DOUBLE_ARG6); + assert (regs_vec_to_double (inregs, 7) == FUNC_DOUBLE_ARG7); + + assert (ret_vec_to_double (outregs, 0) == 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].q == FUNC_LDOUBLE_RET); + assert (regs_vec_to_ldouble (inregs, 0) == FUNC_LDOUBLE_ARG0); + assert (regs_vec_to_ldouble (inregs, 1) == FUNC_LDOUBLE_ARG1); + assert (regs_vec_to_ldouble (inregs, 2) == FUNC_LDOUBLE_ARG2); + assert (regs_vec_to_ldouble (inregs, 3) == FUNC_LDOUBLE_ARG3); + assert (regs_vec_to_ldouble (inregs, 4) == FUNC_LDOUBLE_ARG4); + assert (regs_vec_to_ldouble (inregs, 5) == FUNC_LDOUBLE_ARG5); + assert (regs_vec_to_ldouble (inregs, 6) == FUNC_LDOUBLE_ARG6); + assert (regs_vec_to_ldouble (inregs, 7) == FUNC_LDOUBLE_ARG7); + + assert (ret_vec_to_ldouble (outregs, 0) == FUNC_LDOUBLE_RET); } else - abort (); + return 0; /* Clobber the q registers on exit. */ uint8_t v = 0xff; diff --git a/sysdeps/aarch64/tst-auditmod28.c b/sysdeps/aarch64/tst-auditmod28.c new file mode 100644 index 0000000000..53a2162bfb --- /dev/null +++ b/sysdeps/aarch64/tst-auditmod28.c @@ -0,0 +1,193 @@ +/* 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 +#include "tst-audit28mod.h" + +#define TEST_NAME "tst-audit28" +#define TEST_FUNC "tst_audit28_func" + +#define AUDIT28_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 = AUDIT28_COOKIE; + *cookie = ck; + printf ("objopen: %ld, %s [%ld]\n", lmid, l_name, ck); + 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); + printf (" regs->lr_sve=%d\n", regs->lr_sve); + if (regs->lr_sve > 0) + for (int i = 0; i < array_length (regs->lr_vreg); i++) + printf (" inregs->lr_vreg[%d]=%p\n", i, regs->lr_vreg[i].z); + + + if (strcmp (symname, TEST_FUNC "_sve_args") == 0) + { + svint8_t z0 = svld1_s8 (svptrue_b8 (), + (const int8_t *) regs->lr_vreg[0].z); + svint16_t z1 = svld1_s16 (svptrue_b16 (), + (const int16_t *) regs->lr_vreg[1].z); + svint32_t z2 = svld1_s32 (svptrue_b32 (), + (const int32_t *) regs->lr_vreg[2].z); + svint64_t z3 = svld1_s64 (svptrue_b64 (), + (const int64_t *) regs->lr_vreg[3].z); + svuint8_t z4 = svld1_u8 (svptrue_b8 (), + (const uint8_t *) regs->lr_vreg[4].z); + svuint16_t z5 = svld1_u16 (svptrue_b16 (), + (const uint16_t *) regs->lr_vreg[5].z); + svuint32_t z6 = svld1_u32 (svptrue_b32 (), + (const uint32_t *) regs->lr_vreg[6].z); + svuint64_t z7 = svld1_u64 (svptrue_b64 (), + (const uint64_t *) regs->lr_vreg[7].z); + assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (), + z0, sve_args_z0 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_s16 (svptrue_b16 (), + z1, sve_args_z1 ()))); + assert (svptest_any (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (), + z2, sve_args_z2 ()))); + assert (svptest_any (svptrue_b64 (), svcmpeq_s64 (svptrue_b64 (), + z3, sve_args_z3 ()))); + assert (svptest_any (svptrue_b8 (), svcmpeq_u8 (svptrue_b8 (), + z4, sve_args_z4 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_u16 (svptrue_b16 (), + z5, sve_args_z5 ()))); + assert (svptest_any (svptrue_b32 (), svcmpeq_u32 (svptrue_b32 (), + z6, sve_args_z6 ()))); + assert (svptest_any (svptrue_b64 (), svcmpeq_u64 (svptrue_b64 (), + z7, sve_args_z7 ()))); + } + else + abort (); + + /* Clobber the q registers on exit. */ + uint8_t v = 0xff; + asm volatile ("dup z0.b, %w0" : : "r" (v) : "z0"); + asm volatile ("dup z1.b, %w0" : : "r" (v) : "z1"); + asm volatile ("dup z2.b, %w0" : : "r" (v) : "z2"); + asm volatile ("dup z3.b, %w0" : : "r" (v) : "z3"); + asm volatile ("dup z4.b, %w0" : : "r" (v) : "z4"); + asm volatile ("dup z5.b, %w0" : : "r" (v) : "z5"); + asm volatile ("dup z6.b, %w0" : : "r" (v) : "z6"); + asm volatile ("dup z7.b, %w0" : : "r" (v) : "z7"); + + *framesizep = 1024; + + 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); + printf (" inregs->lr_sve=%d\n", inregs->lr_sve); + if (inregs->lr_sve > 0) + for (int i = 0; i < array_length (inregs->lr_vreg); i++) + printf (" inregs->lr_vreg[%d]=%p\n", i, inregs->lr_vreg[i].z); + printf (" outregs->lr_sve=%d\n", outregs->lrv_sve); + if (outregs->lrv_sve > 0) + for (int i = 0; i < array_length (outregs->lrv_vreg); i++) + printf (" outregs->lr_vreg[%d]=%p\n", i, outregs->lrv_vreg[i].z); + + if (strcmp (symname, TEST_FUNC "_sve_args") == 0) + { + svint8_t z0 = svld1_s8 (svptrue_b8 (), + (const int8_t *) inregs->lr_vreg[0].z); + svint16_t z1 = svld1_s16 (svptrue_b16 (), + (const int16_t *) inregs->lr_vreg[1].z); + svint32_t z2 = svld1_s32 (svptrue_b32 (), + (const int32_t *) inregs->lr_vreg[2].z); + svint64_t z3 = svld1_s64 (svptrue_b64 (), + (const int64_t *) inregs->lr_vreg[3].z); + svuint8_t z4 = svld1_u8 (svptrue_b8 (), + (const uint8_t *) inregs->lr_vreg[4].z); + svuint16_t z5 = svld1_u16 (svptrue_b16 (), + (const uint16_t *) inregs->lr_vreg[5].z); + svuint32_t z6 = svld1_u32 (svptrue_b32 (), + (const uint32_t *) inregs->lr_vreg[6].z); + svuint64_t z7 = svld1_u64 (svptrue_b64 (), + (const uint64_t *) inregs->lr_vreg[7].z); + assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (), + z0, sve_args_z0 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_s16 (svptrue_b16 (), + z1, sve_args_z1 ()))); + assert (svptest_any (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (), + z2, sve_args_z2 ()))); + assert (svptest_any (svptrue_b64 (), svcmpeq_s64 (svptrue_b64 (), + z3, sve_args_z3 ()))); + assert (svptest_any (svptrue_b8 (), svcmpeq_u8 (svptrue_b8 (), + z4, sve_args_z4 ()))); + assert (svptest_any (svptrue_b16 (), svcmpeq_u16 (svptrue_b16 (), + z5, sve_args_z5 ()))); + assert (svptest_any (svptrue_b32 (), svcmpeq_u32 (svptrue_b32 (), + z6, sve_args_z6 ()))); + assert (svptest_any (svptrue_b64 (), svcmpeq_u64 (svptrue_b64 (), + z7, sve_args_z7 ()))); + + svint8_t r0 = svld1_s8 (svptrue_b8 (), + (const int8_t *) outregs->lrv_vreg[0].z); + assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (), + r0, sve_ret ()))); + } + else + abort (); + + /* Clobber the q registers on exit. */ + uint8_t v = 0xff; + asm volatile ("dup z0.b, %w0" : : "r" (v) : "z0"); + asm volatile ("dup z1.b, %w0" : : "r" (v) : "z1"); + asm volatile ("dup z2.b, %w0" : : "r" (v) : "z2"); + asm volatile ("dup z3.b, %w0" : : "r" (v) : "z3"); + asm volatile ("dup z4.b, %w0" : : "r" (v) : "z4"); + asm volatile ("dup z5.b, %w0" : : "r" (v) : "z5"); + asm volatile ("dup z6.b, %w0" : : "r" (v) : "z6"); + asm volatile ("dup z7.b, %w0" : : "r" (v) : "z7"); + + return 0; +} diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 7d6282e599..b9fc286059 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -509,7 +509,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf64_Addr l_addr, const Elf64_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf64_Addr * const reloc_addr = (void *)(l_addr + reloc->r_offset); unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info); diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h index f843ed9bd6..c2ca04181f 100644 --- a/sysdeps/arc/dl-machine.h +++ b/sysdeps/arc/dl-machine.h @@ -329,7 +329,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index c758bba169..c6c3baf05d 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -623,7 +623,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rel *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h index 4dfd957877..fa5d42413a 100644 --- a/sysdeps/csky/dl-machine.h +++ b/sysdeps/csky/dl-machine.h @@ -343,7 +343,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, static inline void __attribute__ ((unused, always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h index 7c5d0e9430..d51df3e444 100644 --- a/sysdeps/hppa/dl-machine.h +++ b/sysdeps/hppa/dl-machine.h @@ -793,7 +793,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, static void __attribute__((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { /* We don't have anything to do here. elf_machine_runtime_setup has done all the relocs already. */ diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 2f0dbc27a9..071e4e3d55 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -641,7 +641,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rel *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h index c9608a51b0..d13c3aa732 100644 --- a/sysdeps/ia64/dl-machine.h +++ b/sysdeps/ia64/dl-machine.h @@ -493,7 +493,7 @@ static inline void __attribute ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf64_Addr l_addr, const Elf64_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h index 30323d62d4..f14e63f8da 100644 --- a/sysdeps/m68k/dl-machine.h +++ b/sysdeps/m68k/dl-machine.h @@ -315,7 +315,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, static inline void __attribute__ ((unused, always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); if (ELF32_R_TYPE (reloc->r_info) == R_68K_JMP_SLOT) diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h index b8cc5a7fe6..f926f27883 100644 --- a/sysdeps/microblaze/dl-machine.h +++ b/sysdeps/microblaze/dl-machine.h @@ -289,7 +289,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, static inline void elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); if (ELF32_R_TYPE (reloc->r_info) == R_MICROBLAZE_JUMP_SLOT) diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h index d7b8341b74..2d19baf84a 100644 --- a/sysdeps/mips/dl-machine.h +++ b/sysdeps/mips/dl-machine.h @@ -729,7 +729,7 @@ static inline void __attribute__((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rel) *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELFW(R_TYPE) (reloc->r_info); diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h index 430ca5d7ae..b76659d442 100644 --- a/sysdeps/nios2/dl-machine.h +++ b/sysdeps/nios2/dl-machine.h @@ -326,7 +326,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, static inline void __attribute__((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); if (ELF32_R_TYPE (reloc->r_info) == R_NIOS2_JUMP_SLOT) diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h index 8d062951ce..a64ff303f0 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.h +++ b/sysdeps/powerpc/powerpc32/dl-machine.h @@ -449,7 +449,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { /* elf_machine_runtime_setup handles this. */ } diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index 3a4a21a412..e33e2a231d 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -1026,7 +1026,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf64_Addr l_addr, const Elf64_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { /* elf_machine_runtime_setup handles this. */ } diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h index ce2b3c3875..944213a939 100644 --- a/sysdeps/riscv/dl-machine.h +++ b/sysdeps/riscv/dl-machine.h @@ -291,7 +291,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index c1d9bb41db..41ec0bab02 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -497,7 +497,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index d405f01a03..057825f309 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -451,7 +451,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf64_Addr l_addr, const Elf64_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h index d14023e749..66c5046631 100644 --- a/sysdeps/sh/dl-machine.h +++ b/sysdeps/sh/dl-machine.h @@ -448,7 +448,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); /* Check for unexpected PLT reloc type. */ diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index 78f53bc499..f0c531d9b7 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -549,7 +549,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf32_Addr l_addr, const Elf32_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index 3fa79d038f..b280a74c9a 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -659,7 +659,7 @@ static inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], Elf64_Addr l_addr, const Elf64_Rela *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index b1a5297b66..101fc71b84 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -540,7 +540,7 @@ static inline void __attribute ((always_inline)) elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, - int skip_ifunc) + int profile, int skip_ifunc) { ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);