From patchwork Mon Nov 15 18:37:15 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: 47698 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 4F3543858433 for ; Mon, 15 Nov 2021 18:38:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4F3543858433 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001530; bh=qI8VOFacanvYjAYQNwKmTOpvwwYLLM2ZrcW0D7UUt7I=; 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=hLrdL9HLgf0wX/Tqdu2v72ROqdr5RxbyBjXv3EsVECuI3hJ3zrJz/RjMQnEIdG4j7 o2W12Ek9DRXsoOZfOeKP0sxb7X1VwrRfcbZOJUYcdNM+toV0+ig/ydWUf4aVqgp+zH aIlEae1PJL3M7AezUAEYzaYReOxaznPFjKTH5gNY= 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 39C033858433 for ; Mon, 15 Nov 2021 18:37:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 39C033858433 Received: by mail-ua1-x929.google.com with SMTP id i6so36896030uae.6 for ; Mon, 15 Nov 2021 10:37:41 -0800 (PST) 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=qI8VOFacanvYjAYQNwKmTOpvwwYLLM2ZrcW0D7UUt7I=; b=XDHOI7CDbu+9SwEMwnsFT2B+dkSaa1CRJodHBhslq2NKEXhO+XzZikh0ZngZNMYci5 w3RvOrNwcdvlRk124DeSX/Zyi/xaUjuMaG9D2Fn4W/8BgtgjhffRonoOrPNqTzwVdG75 8w9hK5QeQOml6vouPKWzCwTMIakJbTHwfEb78Os59TuHGyPgnuHA1prbE7lzBr8FdAQZ MtR4BvQ9blfAzrHKQ1p0u6E6Wus570oiIKGJr6KgFwE4AQFRmPk1IAFK8NKQeA2C8cB9 Z4EnKFerl8uSjYEHByoRAlzECVTFVSe4bHn67raYLq2mIGQARuJaXvj4qLaJZFP5olDF 2dJA== X-Gm-Message-State: AOAM530+oCdUfs/7vKkD5pNjquNsRg9/lWCxzxgiN8Qo7e5TZWtLwasf L0cP8KLGnSQ6M8A5YCFt7cElijPvRoTU0A== X-Google-Smtp-Source: ABdhPJwNtx2kY5hBbEo1e1UmtMFauU5dWIOIlGg9xX0NqzeGDVd4JVYfd5FIZJh1ZbuOld4CA8M8EQ== X-Received: by 2002:a05:6102:d8d:: with SMTP id d13mr44834001vst.15.1637001460550; Mon, 15 Nov 2021 10:37:40 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:40 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 01/20] elf: Suppress audit calls when a (new) namespace is empty (BZ #28062) Date: Mon, 15 Nov 2021 15:37:15 -0300 Message-Id: <20211115183734.531155-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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" 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. Reviewed-by: Florian Weimer --- elf/Makefile | 9 ++- elf/dl-load.c | 72 ++++++++++++------------ elf/tst-audit18.c | 129 +++++++++++++++++++++++++++++++++++++++++++ elf/tst-audit18mod.c | 23 ++++++++ elf/tst-auditmod18.c | 73 ++++++++++++++++++++++++ 5 files changed, 269 insertions(+), 37 deletions(-) create mode 100644 elf/tst-audit18.c create mode 100644 elf/tst-audit18mod.c create mode 100644 elf/tst-auditmod18.c diff --git a/elf/Makefile b/elf/Makefile index a311c3e23c..8f3e3a3602 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -229,7 +229,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-tls-ie tst-tls-ie-dlmopen argv0test \ tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \ tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \ - tst-dl-is_dso tst-ro-dynamic + tst-dl-is_dso tst-ro-dynamic \ + tst-audit18 \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -370,6 +371,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \ tst-auxvalmod \ tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \ + tst-auditmod18 \ + tst-audit18mod \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1537,6 +1540,10 @@ $(objpfx)tst-audit16-cmp.out: tst-audit16.exp $(objpfx)tst-audit16.out cmp $^ > $@; \ $(evaluate-test) +$(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \ + $(objpfx)tst-audit18mod.so +tst-audit18-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 9f4fa9617d..9538bcb7dc 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1058,42 +1058,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* This is the ELF header. We read it in `open_verify'. */ header = (void *) fbp->buf; - /* Signal that we are going to add new objects. */ - 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. */ - 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_ADD); - - afct = afct->next; - } - } - } -#endif - - /* Notify the debugger we have added some objects. We need to - call _dl_debug_initialize in a static program in case dynamic - linking has not been used before. */ - r->r_state = RT_ADD; - _dl_debug_state (); - LIBC_PROBE (map_start, 2, nsid, r); - make_consistent = true; - } - else - assert (r->r_state == RT_ADD); - /* Enter the new object in the list of loaded objects. */ l = _dl_new_object (realname, name, l_type, loader, mode, nsid); if (__glibc_unlikely (l == NULL)) @@ -1515,6 +1479,42 @@ cannot enable executable stack as shared object requires"); /* Now that the object is fully initialized add it to the object list. */ _dl_add_to_namespace_list (l, nsid); + /* Signal that we are going to add new objects. */ + 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. */ + 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_ADD); + + afct = afct->next; + } + } + } +#endif + + /* Notify the debugger we have added some objects. We need to + call _dl_debug_initialize in a static program in case dynamic + linking has not been used before. */ + r->r_state = RT_ADD; + _dl_debug_state (); + LIBC_PROBE (map_start, 2, nsid, r); + make_consistent = true; + } + else + assert (r->r_state == RT_ADD); + #ifdef SHARED /* Auditing checkpoint: we have a new object. */ if (__glibc_unlikely (GLRO(dl_naudit) > 0) diff --git a/elf/tst-audit18.c b/elf/tst-audit18.c new file mode 100644 index 0000000000..b5ed15d07f --- /dev/null +++ b/elf/tst-audit18.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-audit18mod.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-auditmod18.so", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit18", 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-audit18mod.c b/elf/tst-audit18mod.c new file mode 100644 index 0000000000..096a9167c9 --- /dev/null +++ b/elf/tst-audit18mod.c @@ -0,0 +1,23 @@ +/* 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 + . */ + +int +foo (void) +{ + return 10; +} diff --git a/elf/tst-auditmod18.c b/elf/tst-auditmod18.c new file mode 100644 index 0000000000..182992e9fd --- /dev/null +++ b/elf/tst-auditmod18.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 Mon Nov 15 18:37:16 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: 47699 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 7EEA53858027 for ; Mon, 15 Nov 2021 18:39:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7EEA53858027 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001572; bh=pwDJpe84owM+zWuuczRR3fHapXnpzLXffywlytzQSaw=; 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=HbRrtH+OV6azlObB31Eyv50mXxh0sPXBrNaxx/PsaknXikvljbRToJRoDxWCkfoZJ B+rWdpRxDLvG8irABbvZXhn1IQpEYII+fKQrMIy7torxNfGBVKQZg06lsP/5T1Z+xV o5S4rXYrUFLz+ey7ekMXLewpjBJcZfouE4SHdbZ8= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa34.google.com (mail-vk1-xa34.google.com [IPv6:2607:f8b0:4864:20::a34]) by sourceware.org (Postfix) with ESMTPS id 02B8D3858405 for ; Mon, 15 Nov 2021 18:37:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 02B8D3858405 Received: by mail-vk1-xa34.google.com with SMTP id d130so9710362vke.0 for ; Mon, 15 Nov 2021 10:37:42 -0800 (PST) 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=pwDJpe84owM+zWuuczRR3fHapXnpzLXffywlytzQSaw=; b=ZYNcjPNhZrWxMuzRx8hMmVZc86tNkJlzm21V+zN26b5GCW2LAeHnIcWR6/vh2nYVIN +80TDmQjBZx2k3wOo/ZIc01nimZ50DxdKvKKdXPUHcHaI8lAmtjMJboUiYoJ5OJizJ7c bnfLh6xJ4wjZIftH8ngpS4ZlJpQgRL6Lazd/n8tVV5J26t3tl8HsqFdH6LrR/x2CFlxO usm8NFTQmMBN20cUx3MoH4og3GMCEgeeC6HII2ZKT7MgOCF46nVdpKZ0yhB2zhEjhVMH eW2PvG47izASXhE4djH1ECMsOhlarYLfBRO47IPoZMXsO1D0YOoF0ThHrvzcrf0uqLMv L4bQ== X-Gm-Message-State: AOAM532AheqJJSAjdF0PXmWnCAKI+kXIVnu7K1PWSSwn14ASWf8yMcfu ldoc3J6Onbvbp4ZGFccgoCr/vo8B+bEhEA== X-Google-Smtp-Source: ABdhPJx6MWaRQGEQ4vKFvDJaDpeZe6fvEGd0GzJ7B7tq5C5ebFeQDIsnz7cW5il1AjYVK6x6lPtazA== X-Received: by 2002:a05:6122:a13:: with SMTP id 19mr62507368vkn.3.1637001462110; Mon, 15 Nov 2021 10:37:42 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:41 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 02/20] elf: Add _dl_audit_objopen Date: Mon, 15 Nov 2021 15:37:16 -0300 Message-Id: <20211115183734.531155-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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" 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 8f3e3a3602..80ed31edbe 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 minimal-malloc) + debug-symbols minimal-malloc 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 9538bcb7dc..907ab8f5f7 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1517,22 +1517,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 be2d5d8e74..647f476957 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1063,25 +1063,6 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); dlmargs.map->l_auditing = 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) @@ -1100,8 +1081,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 1318c36dce..dec592bf53 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1391,6 +1391,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 Mon Nov 15 18:37:17 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: 47700 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 66B323857C5E for ; Mon, 15 Nov 2021 18:40:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 66B323857C5E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001614; bh=tjVFJ32jv9dRtyiKCWkrMMsaOcXPtcDyC1gd4ka+dyg=; 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=vPvAi2kJfl/RWUJKb0Ge3eby2H0Q3fjmpK2DvXQAu4llfoA1XmzB0w3K5sQ7sWBpO p6jx9pFEW8sGArTWceHw93qcM/yXpVp8S2h1zCJzxsPIXoAGxr3f0EpPspykz99NRA 9cJDKL4IwsBwFpQ6FrOfHB6Qgar0zodFY3+Hd4eY= 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 53C333857C42 for ; Mon, 15 Nov 2021 18:37:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 53C333857C42 Received: by mail-ua1-x92a.google.com with SMTP id p37so35252143uae.8 for ; Mon, 15 Nov 2021 10:37:44 -0800 (PST) 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=tjVFJ32jv9dRtyiKCWkrMMsaOcXPtcDyC1gd4ka+dyg=; b=c1L3jkvVuxbSoVk7wt4oioBDOIrxc01fmfuMGqgMNcBA2/KBnUCAtbPAXyUnKy3hSC 1SLZNGXfFS8B4qiOJien+dTGKYrNvUMe2qbyfuzZ+22IGCMsOtEn3WeoZUxMsUZ5tNBn DK1dYHEiKmHGdq12blLBpLuen0V+8n0bftviKC+HM4blC5VyQ0b4jRxdwucM8gg7FcDX qA0GBHnN8Ay4pA7xa2WpFKscWAIAipvIzSOROKLWHEdtWbAcLZ9MIyk/57FyoHt4LfWh kxgqlJZdTSrAxPmHcRY/V6V9VBzQobO20IzGvRM8afdbQJq43ZhSt6MCURUC4aWErCZ9 sKXg== X-Gm-Message-State: AOAM532j8HTFop33Kep/37WPpZEbYEC9L1RMQ94NcyPrlRd3hqF3g3Hn 1R0qRRaPpBCLyPDPd1bbLiKTmNy2tBCUpQ== X-Google-Smtp-Source: ABdhPJxXUR+quUnvYVh9pFfgE11LcnxWGJOYgxfVPgPJxfliUyHMkf2v8z+Eq6pF0+W5ud4onPy2wQ== X-Received: by 2002:a05:6102:3232:: with SMTP id x18mr40763906vsf.38.1637001463655; Mon, 15 Nov 2021 10:37:43 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:43 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 03/20] elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid Date: Mon, 15 Nov 2021 15:37:17 -0300 Message-Id: <20211115183734.531155-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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. Also 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, i686-linux-gnu, and aarch64-linux-gnu. --- elf/dl-audit.c | 23 ++++++++++++++++ elf/dl-close.c | 54 +++++++------------------------------- elf/dl-load.c | 20 +------------- elf/dl-open.c | 20 +------------- elf/rtld.c | 31 ++-------------------- sysdeps/generic/ldsodefs.h | 7 +++++ 6 files changed, 43 insertions(+), 112 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 4f5cfcc1c3..79dbb41094 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -472,25 +472,7 @@ _dl_close_worker (struct link_map *map, bool force) #ifdef SHARED /* Auditing checkpoint: we will start deleting objects. */ - if (__glibc_unlikely (do_audit)) - { - struct link_map *head = ns->_ns_loaded; - struct audit_ifaces *afct = GLRO(dl_audit); - /* Do not call the functions for any auditing object. */ - if (head->l_auditing == 0) - { - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) - { - if (afct->activity != NULL) - { - struct auditstate *state = link_map_audit_state (head, cnt); - afct->activity (&state->cookie, LA_ACT_DELETE); - } - - afct = afct->next; - } - } - } + _dl_audit_activity_nsid (nsid, LA_ACT_DELETE); #endif /* Notify the debugger we are about to remove some loaded objects. */ @@ -785,32 +767,14 @@ _dl_close_worker (struct link_map *map, bool force) __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 907ab8f5f7..848d3e08eb 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1483,25 +1483,7 @@ cannot enable executable stack as shared object requires"); 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. */ - 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_ADD); - - afct = afct->next; - } - } - } + _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 6ea5dd2457..e2f2e713e7 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 647f476957..dc20643ee9 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1759,18 +1759,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 @@ -2451,23 +2440,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 dec592bf53..ea481cbe84 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1392,6 +1392,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 Mon Nov 15 18:37:18 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: 47701 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 AB5873858405 for ; Mon, 15 Nov 2021 18:40:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB5873858405 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001656; bh=P2rp8xS2TNE/sYtCL1xjjy6mV38GsS4JLueAW63lW7U=; 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=pekg7exOXN1fs/ELKCKDi1WIfIWASAyw3WX8FSckWG82HJjUnIJGhpaYtZPwx1xPT 4RqXT3Jx6pjdaMexUI557+QJKL+MlSPxMvC8wKZmenF0R89p95wJlb23M3Kpns9g6m xA+4vQ8s/Hpc3RvQM3FUpgrw/4Ba1cl+37v0Gj58= 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 D98F33857C72 for ; Mon, 15 Nov 2021 18:37:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D98F33857C72 Received: by mail-ua1-x92d.google.com with SMTP id p2so36881889uad.11 for ; Mon, 15 Nov 2021 10:37:45 -0800 (PST) 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=P2rp8xS2TNE/sYtCL1xjjy6mV38GsS4JLueAW63lW7U=; b=XEGP7hpffK139CVxu0w+k1GNzmB2kIEJ2J5Ep/dqNHOabNIoNS0sl9dcz6VKaTbaPI y9v9B6Q+wXHTTm0WBZkXf7re/7d8gKhEvw8dKKZ3PAVEZXzLpvfqrK5f+5t6L+kgrhvw nPub02zM8Y/84seB8vbxHeT1UmBtPwIpvcDl8OVJbP+hR6XEypZR0t/GuCieBL6KdLfH VJTklGggQagnKfTGWIqzwa6f6dgt+f7f/lHi5nTNUpMRXS6ERPLV5zd02GJmMjJFcM81 pAyU2niM+5zDkOK/ZZSYoGf4mbR4Bo1SLXkwvwkfQI/QIa5vxEb6EnL6152LamDLMrFt FW3g== X-Gm-Message-State: AOAM530efm1M0cEqrDSOqXGiIFgPP6v1NjxVP61+heT4+18nq5onzOnb WKWSMYz/Ga1exsgxY160lt+D0ZkQHQoX7w== X-Google-Smtp-Source: ABdhPJwMjt3Yee2+/3VxcUqe3eZ5vjLg9Af1OLAvKPYOClIWOdbYeDJMLCrUCEPiCe63yD8SyuRX0g== X-Received: by 2002:a05:6102:105b:: with SMTP id h27mr46447732vsq.60.1637001465246; Mon, 15 Nov 2021 10:37:45 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:45 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 04/20] elf: Add _dl_audit_objsearch Date: Mon, 15 Nov 2021 15:37:18 -0300 Message-Id: <20211115183734.531155-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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_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 848d3e08eb..e28893b779 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1595,33 +1595,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) @@ -2059,36 +2034,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 ea481cbe84..b1c76361d2 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1392,6 +1392,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 Mon Nov 15 18:37:19 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: 47702 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 84446385843A for ; Mon, 15 Nov 2021 18:41:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 84446385843A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001703; bh=BlfIWmP9uFkKprMvnLNh46G6/Nk5ispu6Jff6q0zn2g=; 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=sbg2102maqD582EIubbdoHbeAmRCe34/G902x0h7d8BxSdBLj/MbvLv0G4OXyUPnM zxkvF//VDHo11k4eGoKmXutKIOgXwH38RRwmoJRYL6igbcCVQnuKZQqsf4+8NlJ8+v 9nWNlefpkdU0MXeZw25crw4V5embeK0VOIt3TQEU= 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 8F3F83857C7A for ; Mon, 15 Nov 2021 18:37:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8F3F83857C7A Received: by mail-ua1-x92a.google.com with SMTP id p37so35252468uae.8 for ; Mon, 15 Nov 2021 10:37:47 -0800 (PST) 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=BlfIWmP9uFkKprMvnLNh46G6/Nk5ispu6Jff6q0zn2g=; b=Fje+qLf8GZsnfuWW29lGYay7Bpb20OBIh/OSA2Dw23Ql3G0IQExcIUdWQwUQFAT6J8 X2iyAL9YKmT8tOPDvF1cv+XypoFLr0+qba7ptuaJpWcjhPfEuLkoCAqhtesFqpxBcCzq crdURltO0UbrdhWmvoXTIJyOoi7CdBYmB4vT9AxQRV02WnHpLq1GE6KB5iUlV1P/DUTG C2TEPElJ/5BcGSocbSQIFXBxfc1ZUrL+uUKj/flFa5qKJyKRZTYixQTscN0vjHIccNBu Zdy128i1o+lJgVmoc9RVKjmQ9O2WkdG0szybqJQkiCt2VNJxOBPfEfk/AytKl6/HpULC gLfA== X-Gm-Message-State: AOAM533GxCC64AdrWSVcWf6wRfiY3CxuV9N654cp8HYqun42R+CjN14+ qlgrxzSShvV7tABBHb/5WMp0GqHGygGptA== X-Google-Smtp-Source: ABdhPJwKHFHExy7BZ2Xjcv/2NMTp0pkuSwXsyAN6lhbcA0h5SEzJ14zRVmcEGFGwzX58h9Eqj8HYXw== X-Received: by 2002:a05:6102:242f:: with SMTP id l15mr46025595vsi.11.1637001466827; Mon, 15 Nov 2021 10:37:46 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:46 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 05/20] elf: Add _dl_audit_objclose Date: Mon, 15 Nov 2021 15:37:19 -0300 Message-Id: <20211115183734.531155-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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_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 79dbb41094..df4e948498 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -260,9 +260,6 @@ _dl_close_worker (struct link_map *map, bool force) _dl_sort_maps (maps, nloaded, (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; @@ -296,22 +293,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 c683884c35..1720cfaeb8 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -146,21 +146,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 b1c76361d2..82dbc66d79 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1405,6 +1405,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 Mon Nov 15 18:37:20 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: 47703 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 1800A3858027 for ; Mon, 15 Nov 2021 18:42:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1800A3858027 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001772; bh=wdgPr3U1WDBHj1nxoT+D4nkEocKZ9+z+svyyqcsm7Vc=; 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=Ws3PwW4sgz5ibcB41dBF2Uqvtk3wsD65T6IMjPbgmoWF0Mtqv08lmrQaqeRGhtsOP m7OsrNGyexvfsRP3PE5AF3+mfN9dbkkLxreRbBUDvDxIGp0TDy0RmPtdFAxplrZbyK coDt07H05hT9UuDBwi3MvfRxM14gWaudzyXpBBL4= 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 F27A73857C67 for ; Mon, 15 Nov 2021 18:37:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F27A73857C67 Received: by mail-ua1-x929.google.com with SMTP id i6so36896793uae.6 for ; Mon, 15 Nov 2021 10:37:48 -0800 (PST) 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=wdgPr3U1WDBHj1nxoT+D4nkEocKZ9+z+svyyqcsm7Vc=; b=IINdZJS9rS/Cn6tqEbrdWJZ+/8kFxjhvBUKSiuerEtkLwX2OKyu4JtPzbXYqh3O/1A ZxuP4p81W23vhtiKvaUiW4BRkT9pNXyTdTToLPhEtbGvdaiu7CpbLblhbpVDdNjrNRFW Hs0/Sj1sroAo+npqZdUBjGrX1mkICkD19ybrS0CIp/iu/jfOUgWrBsifXquJfjQvGVlS tsXeUynuCSCveIxLR4YIvxJuZZ9THjaebnG8uTXsLuqVWecwQq6NW6+OKZBhnx9hhcfe McpCXt2IFQK57R1287dWblr32z4d+ZRsQKR7YZrVIeA8M9+A79eK+TpJrWXmlIiA1WT4 BeVw== X-Gm-Message-State: AOAM533F6Bdpq0MyljSQ7DsOpluZDFmKrYTQK7HlK18clCLw2iBTh7/q SjiXfAFK9PfloPuhyE0qHLJctSOt2QPaLg== X-Google-Smtp-Source: ABdhPJxyynObVoiamlbmrXU7FwQ90EKPdVz5pNcjfSr7i+ZXYSuvob1C9NKARz4Aa+4kNQ/yCmjWLA== X-Received: by 2002:a67:f794:: with SMTP id j20mr46068480vso.54.1637001468388; Mon, 15 Nov 2021 10:37:48 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:48 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 06/20] elf: Add _dl_audit_symbind_alt and _dl_audit_symbind Date: Mon, 15 Nov 2021 15:37:20 -0300 Message-Id: <20211115183734.531155-7-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 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-sym-post.h | 47 +------------- sysdeps/generic/ldsodefs.h | 6 ++ 4 files changed, 130 insertions(+), 46 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-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 82dbc66d79..dccd43b39d 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1406,6 +1406,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 Mon Nov 15 18:37:21 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: 47704 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 DECA23857C7A for ; Mon, 15 Nov 2021 18:43:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DECA23857C7A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001814; bh=msGA8aJBEAqfHvobJ2ymforwnbh01IK3KXaH4yt8g/s=; 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=fqJ74ErdhV6w3JF1/qgPsj2SfCFACLZ1OsjVMEehWlTfRROxWn53/w6VBz5yMmORp 4+xHj2ZX9n4vnvLw5WaOC8jqpQ5+ynrPDIfA5fya53ViM2sxu6k8UzwEazxvFUJfmD HcEolHjil24yagOSbFdutF5Mj1HhNb94vNeFcBPE= 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 7DB88385780F for ; Mon, 15 Nov 2021 18:37:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7DB88385780F Received: by mail-ua1-x935.google.com with SMTP id n6so20338054uak.1 for ; Mon, 15 Nov 2021 10:37:50 -0800 (PST) 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=msGA8aJBEAqfHvobJ2ymforwnbh01IK3KXaH4yt8g/s=; b=YRcGCL8iGrcZxnL4ubkoAV9aIflf2GhuEwhhPOeCPqeXtdD44xmJpNKDQ/PmMkPeTN 50DpX66ZWOAKBXqsomONAoiCjvqEKfjmQn0IrVhmv/At4mLs3vc2MZb7lqEnzXSu2qbx VmIyWJDa/Csk/E7eZZmYGPVD2Yl6Uk+qMayA7vIfmauH6DV/DZN4gk8YcPUH0KbJUfVQ 3+b5j5uZdQE2yIhbjPHvyLRmAdLvrF4TRQFAu0TouO3z/k1dvz/2VToW1GhMPbS26C1D FnTY9J6hTLYmGMZAWnZyqougpNjXGoOeO+ZGk+glgUrLdJipS+5v5rmV13TzmY69+cZB Skbg== X-Gm-Message-State: AOAM533GCeB7QiliIHPzuVrt6BA9gzeu0Sfq6usH+WnlyiXXlltjjl8z 6YJ4+U7kNj+rdjPy4x//4md1Zjvdv/N/XQ== X-Google-Smtp-Source: ABdhPJwazax/TvihDXLFmNm1w0CnziAOV0E3n8WnET14U8Xg9iy/ZIT/g/0J8cZypDXKXXtdvZKxlQ== X-Received: by 2002:a67:c79a:: with SMTP id t26mr35553040vsk.37.1637001469974; Mon, 15 Nov 2021 10:37:49 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:49 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 07/20] elf: Add _dl_audit_preinit Date: Mon, 15 Nov 2021 15:37:21 -0300 Message-Id: <20211115183734.531155-8-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 dccd43b39d..b7ed59bf51 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1406,6 +1406,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 Mon Nov 15 18:37:22 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: 47705 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 CA0CC3857C5E for ; Mon, 15 Nov 2021 18:44:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CA0CC3857C5E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001861; bh=B2Y+iRXdR03SikHhF+BJt7Cl6vLklfc3iKA0scMwkUo=; 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=o15UsT76XLC4eTnFssUbM9r1my2EhsyvtAtEGD9q/vnMuBCLzbFidR6gpZ9Y5kmVO ILZnkDcwABzEEHZreLrFwb0zWAA1aJkWoePXJs6PZyLlNoXI/l0YxlcyPetQUD6JBo 8Li/ch/Mhwl9sTEM4tpp1L42eQYKtzy5/1noHX50= 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 29B053857C42 for ; Mon, 15 Nov 2021 18:37:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 29B053857C42 Received: by mail-ua1-x92a.google.com with SMTP id n6so20338279uak.1 for ; Mon, 15 Nov 2021 10:37:52 -0800 (PST) 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=B2Y+iRXdR03SikHhF+BJt7Cl6vLklfc3iKA0scMwkUo=; b=Xp/PzYXxoJe9AOjySmSdPK4Drci0IdHD2idv00+V7Y+sQTGZnob1/XVFcNw2FJsEI4 EseAMQJqxC/oExcgNlLX2TRjEFzgnAz3oLLnqyDBOVrfmjD+avPpBzWdaGwpk0olSMOm psD9oq015af3PKrOVGUSunFwNMqPqSFKWJ9t0q6/0WmmPndMeMMaXmWWjBGoACi1dd+Z 6bnVQAJe5DQgIaGwlfP8fwIAwYGdqlVfy1w0Pdl5sxV3EhC8MA3GGQ0RRcAHdXKBKV/A AlRq0hF5jYeOATorw+sbfuO6JDD+526e7KjCRqU2sJEvyyNeMaj4VkUE7y6R+nHZTUMq spMQ== X-Gm-Message-State: AOAM532eUlkD5716l184a601J83cFVO7A4ANnR/1V+dejQVButjHL2sV K6LpE+lNgaipwgxAP+vWMO0MtS3KU3c7AA== X-Google-Smtp-Source: ABdhPJzAg+mUrbbq60daruxuyrZKxOc4xtr90gtDZexxjL3nMtFWT3BBBEqvoHBvW9pKERGF36WApw== X-Received: by 2002:ab0:32c4:: with SMTP id f4mr1346674uao.51.1637001471483; Mon, 15 Nov 2021 10:37:51 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:51 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 08/20] elf: Add _dl_audit_pltenter Date: Mon, 15 Nov 2021 15:37:22 -0300 Message-Id: <20211115183734.531155-9-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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. Reviewed-by: Florian Weimer --- 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 61c260ddb8..1db5e211db 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -397,78 +397,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 b7ed59bf51..abff37ab86 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1413,6 +1413,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 Mon Nov 15 18:37:23 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: 47706 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 1C333385780F for ; Mon, 15 Nov 2021 18:45:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1C333385780F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001904; bh=XsR+uoQx3NpH36LkNnpo1BkpMpe/4fZ53+9gvYOpXhU=; 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=ZEFm9CtuIxWhlZON/f9d+xSrJnEo+jsDio/QLRVaIBZJFGAPKcpwNnz2ncxti5GC2 ptrlbZt4H0wthMN6S24aWlpAUCXuhCQ1SGPNuI5PzXtYe0V9DhGTdqvSPXv2GVHVNA 04QX6RibSB4ZOlI+wv/aInoY3t2JdxR7+DPCfE/k= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ua1-x92f.google.com (mail-ua1-x92f.google.com [IPv6:2607:f8b0:4864:20::92f]) by sourceware.org (Postfix) with ESMTPS id 01B653858018 for ; Mon, 15 Nov 2021 18:37:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 01B653858018 Received: by mail-ua1-x92f.google.com with SMTP id p2so36882608uad.11 for ; Mon, 15 Nov 2021 10:37:53 -0800 (PST) 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=XsR+uoQx3NpH36LkNnpo1BkpMpe/4fZ53+9gvYOpXhU=; b=vg+CNXVP5eT6ivURgppt/0FJlXFmDyIib5Fvr56Ian9WP1ZILgfQNocUd6V1Axsmp6 JRK68bkXrMQoB1vUi8i75Jjhqf4xrZALDFTTq2B8LrDS8De+OIaIvB4UIF5ACjrigtbB zNIhjBXjHvb70ii6UKgNi/Sn6VJXYWWVOJ+gLAtPWJOAnz6ChTUJaizA5w+s3YWrZNj6 TqORnLuUqV8b76ZVEd8NXpUzKeOh9tMxyskJv3vg/olrKZLaTB8rrH0njkYGUFsgWZC4 mCr6UdHbs4zBku3894cpYnihN4wR98aEonzF1c2axo5Xojd5Vq8AoTNvyLy3dtr6TGbH ReBA== X-Gm-Message-State: AOAM531QwboeaINBW3MlXgvDmjHW9lq3JsRPzjd0bbmvnKm659UaO35I 7VAAoxG8uyq1IB/zFjJcU47LquAKETQQTw== X-Google-Smtp-Source: ABdhPJxycR1QkhVxZKQpZ4szmuquav02VVCrOCqynTgooj3CUaUs1Qc9pYkSmPJVEgXnGIznmOL84A== X-Received: by 2002:ab0:7c7a:: with SMTP id h26mr1286538uax.103.1637001473153; Mon, 15 Nov 2021 10:37:53 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:52 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 09/20] elf: Add _dl_audit_pltexit Date: Mon, 15 Nov 2021 15:37:23 -0300 Message-Id: <20211115183734.531155-10-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 1db5e211db..03da689503 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 specified in the PLT of the given shared object, and return the resolved @@ -52,7 +44,7 @@ function. */ DL_FIXUP_VALUE_TYPE -attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE +attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE _dl_fixup ( # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS ELF_MACHINE_RUNTIME_FIXUP_ARGS, @@ -148,7 +140,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, @@ -409,52 +402,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 abff37ab86..d419a62dbd 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1416,6 +1417,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 Mon Nov 15 18:37:24 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: 47707 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 CF68E3857C71 for ; Mon, 15 Nov 2021 18:45:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CF68E3857C71 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001951; bh=K49iQHOyjn/nAx5o1VxoTOpKAzSgXyFm4d+bta+1scc=; 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=c0sWhQ1XQ2aGYJ9u3Jqb4tLW/CRX2VQS8pHxWYEHKi3M74RsltfouXXipEXJ4sHIN mamrEnfnbIsCt12Pr2WXvBl3ax8c5at/T1q5drf1zT9vETmSV4zf8u3sP/u82aIuPJ GY5veQ0A3v503bp3GX65EKPUfOKmODh1VmsUHdbs= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa34.google.com (mail-vk1-xa34.google.com [IPv6:2607:f8b0:4864:20::a34]) by sourceware.org (Postfix) with ESMTPS id 825163857C44 for ; Mon, 15 Nov 2021 18:37:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 825163857C44 Received: by mail-vk1-xa34.google.com with SMTP id u68so2414988vke.11 for ; Mon, 15 Nov 2021 10:37:57 -0800 (PST) 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=K49iQHOyjn/nAx5o1VxoTOpKAzSgXyFm4d+bta+1scc=; b=v+fTkvf+1+q8D1yKVHhyBJ6gBfkFE+BwWP68+kE8hG3qzBzV1tiGP2WX1mRfJXuf+K 6eZWKjBv4bbiKkKb4YLinNwYJ26GndDOpkjUuIulV4om8HWuNW2g/dgnJVtaEfYVvjFz iSmQ7uu76GqGzx3IOrpPTFFQPEkh3w3nGCTWcpYaxCm5pm9vanWGCdYpmfQ+fBY46sap wcFfF59mbkmVyWzKwP5Zeg4IdSZlm07svel6crE2stVG+7hU38mjGYhMQOzXnASk1MhP WgTyWNji1E497vRFFWQC7JXqw2P0942z69ySV9JwSl4674noHXJFX+B9LCVGxxPsm5oZ MKrw== X-Gm-Message-State: AOAM532aAIu1oqIBjGduzDrPEq7KIdOEP338zJUjU7nGLN8QC8HAAly6 HBc/fnGAMVl7qRR79e7y0VQAHJAlVRW43Q== X-Google-Smtp-Source: ABdhPJy7+OZOo1qTx2cTsCadnV0CseJUNEWHQpprexoYhgnItdlp+ptLO70gF7IrwYolxhic56mbdA== X-Received: by 2002:a05:6122:2193:: with SMTP id j19mr63319417vkd.7.1637001476684; Mon, 15 Nov 2021 10:37:56 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:56 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 10/20] elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) Date: Mon, 15 Nov 2021 15:37:24 -0300 Message-Id: <20211115183734.531155-11-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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: 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 | 12 +++++ elf/dl-reloc.c | 20 +++++++- elf/dl-runtime.c | 110 ++++++++++++------------------------------ elf/rtld.c | 8 +-- elf/tst-audit19a.c | 39 +++++++++++++++ elf/tst-audit19b.c | 94 ++++++++++++++++++++++++++++++++++++ elf/tst-audit19bmod.c | 23 +++++++++ elf/tst-auditmod19a.c | 23 +++++++++ elf/tst-auditmod19b.c | 46 ++++++++++++++++++ include/link.h | 2 + 11 files changed, 294 insertions(+), 87 deletions(-) create mode 100644 elf/tst-audit19a.c create mode 100644 elf/tst-audit19b.c create mode 100644 elf/tst-audit19bmod.c create mode 100644 elf/tst-auditmod19a.c create mode 100644 elf/tst-auditmod19b.c diff --git a/NEWS b/NEWS index f10971b180..427cd2a27d 100644 --- a/NEWS +++ b/NEWS @@ -184,6 +184,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 80ed31edbe..d2a71f73f1 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -231,6 +231,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \ tst-dl-is_dso tst-ro-dynamic \ tst-audit18 \ + tst-audit19a \ + tst-audit19b \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -373,6 +375,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \ tst-auditmod18 \ tst-audit18mod \ + tst-auditmod19a \ + tst-auditmod19b \ + tst-audit19bmod \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1544,6 +1549,13 @@ $(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \ $(objpfx)tst-audit18mod.so tst-audit18-ARGS = -- $(host-test-program-cmd) +$(objpfx)tst-audit19a.out: $(objpfx)tst-auditmod19a.so +tst-audit19a-ENV = LD_AUDIT=$(objpfx)tst-auditmod19a.so + +$(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so +$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so +tst-audit19b-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..64a96c36e8 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -205,12 +205,28 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], int skip_ifunc = reloc_mode & __RTLD_NOIFUNC; #ifdef SHARED + bool consider_symbind = false; /* 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 +#else +# define consider_symbind 0 #endif if (l->l_relocated) @@ -272,7 +288,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 03da689503..9a38eea7cc 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -131,6 +131,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; @@ -290,84 +321,7 @@ _dl_profile_fixup ( auditing libraries the possibility to change the value and tell us whether further auditing is wanted. */ if (defsym != NULL && GLRO(dl_naudit) > 0) - { - 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 dc20643ee9..73a852ad42 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1015,13 +1015,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-audit19a.c b/elf/tst-audit19a.c new file mode 100644 index 0000000000..36b781f9be --- /dev/null +++ b/elf/tst-audit19a.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-audit19b.c b/elf/tst-audit19b.c new file mode 100644 index 0000000000..300197ca2e --- /dev/null +++ b/elf/tst-audit19b.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-audit19bmod.c b/elf/tst-audit19bmod.c new file mode 100644 index 0000000000..9ffdcd8f3f --- /dev/null +++ b/elf/tst-audit19bmod.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-auditmod19a.c b/elf/tst-auditmod19a.c new file mode 100644 index 0000000000..2296382a1c --- /dev/null +++ b/elf/tst-auditmod19a.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-auditmod19b.c b/elf/tst-auditmod19b.c new file mode 100644 index 0000000000..52bb88c7d7 --- /dev/null +++ b/elf/tst-auditmod19b.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 c1c382ccfa..6a9f788d2b 100644 --- a/include/link.h +++ b/include/link.h @@ -367,8 +367,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 Mon Nov 15 18:37:25 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: 47708 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 AE4713858027 for ; Mon, 15 Nov 2021 18:46:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AE4713858027 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637001994; bh=wqbqYyKBasE1In1m1Pc6DLWVxrEUGBa3DVk/8vPaxzw=; 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=gBg1oLU+Dm39bepuA89TYP+cQECH5WMdwmJtKjFz6c/NZ1fQ/8U1kn2vmKIuNd0bR qkQ9xxPmv5oMz+3cOqGJAW1KJ9tp/0D7tdZHp57ms7Wwi1XeBXgwenRDtQCVNa7sRb 8roynyS6qMusmODOKaGrcGjG+r2vHAhH3wDIK1hI= 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 2B8063857C63 for ; Mon, 15 Nov 2021 18:37:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2B8063857C63 Received: by mail-ua1-x936.google.com with SMTP id ay21so36869153uab.12 for ; Mon, 15 Nov 2021 10:37:59 -0800 (PST) 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=wqbqYyKBasE1In1m1Pc6DLWVxrEUGBa3DVk/8vPaxzw=; b=S8tER7I1im+eV6Ti6Zpy3e5KX3Qt7QeFJm2lklcuNq4yXGiX3Qv1PVYZ9II51yMea7 ww/lfHPBDosYKUljI0MYcsCUMyjwgq6/tqPmgaPw2TI2hYnCadThM8TEc2AXuYDO2PWk xI9vu7GcwBhveLOuFKGyyREHpDvEuH29ECLvmlV21rinjv/IUwHd4wUh9wMLPHUK7GBo cD+bnuBGWr4MsBQvdZU6njHPitfjwo5S9OGIHCrak6zUsngQ9Xr962nvxeUrhS1MZ4IU l690O5KKAYt3cVU739MNYUI4T/8XHURoKVPAOXyV1YaCuC8YXt52zBubrz0oouw5j+ou usiA== X-Gm-Message-State: AOAM531PgoM228E3jktRZ0I9meny01balqoSfJH8QSblU1Tc6EwzxeGc 4YYVuC8XOy4Nd8keH1saz1E9YWRnUYcJEw== X-Google-Smtp-Source: ABdhPJxkUkobnZAZC/sBAJuLjJt0k2M3X5AxR1cWTBF8ebYLPqzoX2HlN0RuYWkfraYfOEMOI7e0EQ== X-Received: by 2002:a05:6102:e07:: with SMTP id o7mr46517100vst.27.1637001478536; Mon, 15 Nov 2021 10:37:58 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:58 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 11/20] elf: Add audit tests for modules with TLSDESC Date: Mon, 15 Nov 2021 15:37:25 -0300 Message-Id: <20211115183734.531155-12-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella 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 | 25 +++++++++++++ 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, 240 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 d2a71f73f1..19ec680144 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -390,6 +390,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..e4b835d1f1 --- /dev/null +++ b/elf/tst-audit-tlsdesc-audit.c @@ -0,0 +1,25 @@ +/* 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 + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} 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 Mon Nov 15 18:37:26 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: 47709 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 A94BA3857C44 for ; Mon, 15 Nov 2021 18:47:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A94BA3857C44 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002041; bh=hf5tARBz92ZEm/vZl4Y0l0cz8TzjGknh/Ho8cz7Ryxg=; 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=V/d806Shq2hQcGiirx7izNyqSg9dWJxiNG8uUkyH/dh0kjGQcphm3u2xbz84mWKwb 3wGf+mus9tT2wlZpMp5c3ObJK05NPfwcWTfnrRi2AbHHhsRDcvl/AuienAK5CWOMx4 MjU26RSjC83BUuxh+mTqiz/Al9EUBe3BHIYa9LPo= 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 BF7953857C4F for ; Mon, 15 Nov 2021 18:38:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BF7953857C4F Received: by mail-ua1-x935.google.com with SMTP id i6so36898074uae.6 for ; Mon, 15 Nov 2021 10:38:00 -0800 (PST) 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=hf5tARBz92ZEm/vZl4Y0l0cz8TzjGknh/Ho8cz7Ryxg=; b=R7BqaLZ/QG5nAqaZKfkw7TZeUDGGQDY4sirxjdmiR1nN/YhwA9JO/QBagHqD+R6s6y COWDLotjhd55KrKwPwbhMBKixLOOCqxWSMDewkkIa0Hzjr3C2mSNzu5W9gWqlg2G9ss4 Qv9xhrqt7F+UPWpswKgjJNKJfu4NS1p40W5KyDIHIAU0Nd949A1+Wnfj3qWNXIyZyUjJ GmMW/Qb9iKl6E0R79/c3GV83Cwn9xiV6TK0DF2CHYoXX0QVkz5vIo0SC4EAr/7Rpa/A/ 8XxAz+/6AItiJlzzxNaMD+9azM/KKlY1JhLjNMXX1nrnxVrAf7m0KGYeROHYNOc3IMtu SnNA== X-Gm-Message-State: AOAM533FxaVv4xCv3jI4l1FEMrN7p5s2ZGY50D/5//jKxhRw3swswk4C xJc2rc4T5h51eBj4dVNvCGxGnb9DMaqA2A== X-Google-Smtp-Source: ABdhPJzaMbvh+b3P23FpL9/l9ifGPMgVAojT3aqJ+Kj+TpYxF3djl+2SHf4mFN2lqJ+yFVqAUCezJQ== X-Received: by 2002:a67:c982:: with SMTP id y2mr45266083vsk.15.1637001480115; Mon, 15 Nov 2021 10:38:00 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.37.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:37:59 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 12/20] elf: Do not fail for failed dlmopen on audit modules (BZ #28061) Date: Mon, 15 Nov 2021 15:37:26 -0300 Message-Id: <20211115183734.531155-13-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 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 be seen if the state is consistent, since _dt_main() resets it. This patch removes the assert. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. Reviewed-by: Florian Weimer --- elf/Makefile | 5 ++++ elf/dl-open.c | 2 -- elf/tst-audit20.c | 25 +++++++++++++++++++ elf/tst-auditmod20.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 elf/tst-audit20.c create mode 100644 elf/tst-auditmod20.c diff --git a/elf/Makefile b/elf/Makefile index 19ec680144..4636a2743a 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -233,6 +233,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit18 \ tst-audit19a \ tst-audit19b \ + tst-audit20 \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -378,6 +379,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod19a \ tst-auditmod19b \ tst-audit19bmod \ + tst-auditmod20 \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1570,6 +1572,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so $(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so tst-audit19b-ARGS = -- $(host-test-program-cmd) +$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so +tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.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 e2f2e713e7..4f4d72e325 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -914,8 +914,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-audit20.c b/elf/tst-audit20.c new file mode 100644 index 0000000000..6f39ccee86 --- /dev/null +++ b/elf/tst-audit20.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-auditmod20.c b/elf/tst-auditmod20.c new file mode 100644 index 0000000000..c57e50ee4e --- /dev/null +++ b/elf/tst-auditmod20.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 Mon Nov 15 18:37:27 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: 47710 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 EFA3C3857C44 for ; Mon, 15 Nov 2021 18:48:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EFA3C3857C44 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002084; bh=NGsRu3t2hMsCjP2zwr2CsUPaUcyxRHWeyQcPuilpZYU=; 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=TK1iUdLSK9dluljK59DwIgtIJVTdCHRlj1OYYKLc/IuNVHPLB9r0kxdl7b0vechqA LqrhpARdQo9AI55bm0whfkgSbnWuyULAXBafsSR1I9fS0l23Ye/ex8M6ET5pVw6qyP YMRPPNpkVThpuSuLpQe2ZUZLhHLfdOVriJIC6hdc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa2f.google.com (mail-vk1-xa2f.google.com [IPv6:2607:f8b0:4864:20::a2f]) by sourceware.org (Postfix) with ESMTPS id 523C13857C44 for ; Mon, 15 Nov 2021 18:38:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 523C13857C44 Received: by mail-vk1-xa2f.google.com with SMTP id f7so9695879vkf.10 for ; Mon, 15 Nov 2021 10:38:02 -0800 (PST) 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=NGsRu3t2hMsCjP2zwr2CsUPaUcyxRHWeyQcPuilpZYU=; b=24kteKyrpsfqM0QEFGykwx25QQzb7rVaZh5XkYMWOLFR+uDUPk7FwZqYS+zxrdetOH KgPbxNOhgr98UHCDbccfNyMtq2vPKAYTXacQHeNmjn82cCK27GUNVnxUjLuhT8q6Mmwd 8MsHlEmtkRccEQRRXvaxlCg4DeJ/ZWfjbPNHDrISLUj6iyylmyRPGzEBW8LgPY6SrUb/ Zgw6exk+GQJO0TF8NFPNjH23n8pWv5h00JanvvqlYVHAgyt6UGi5bptUKXpmUrU6jvob F4Z+QekxBInIW6n4K4TrxTOuNSiyIFFtH6dDM77TCENqPx8oFFZmcxpes2LMyG5C1+Hw PBpg== X-Gm-Message-State: AOAM530jdKYp4tkmjDB05lNLGWztsZjieYD74ZXZ0qxdjYenuBbDux+s WYSZBBiFEBQ1U05rlEyJFkcWMNHsp3xsxw== X-Google-Smtp-Source: ABdhPJxSIDY5rrqJz4p9qdtlIhqdQJ9ZHXsEAqMu1U/7AkAKH0BEnjri9HTQdoTmeyxIr3j9tCDmmw== X-Received: by 2002:a05:6122:1813:: with SMTP id ay19mr62015524vkb.24.1637001481658; Mon, 15 Nov 2021 10:38:01 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:01 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 13/20] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Date: Mon, 15 Nov 2021 15:37:27 -0300 Message-Id: <20211115183734.531155-14-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 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 | 8 +++++ elf/dl-object.c | 3 ++ elf/dl-tls.c | 16 ++++++--- elf/rtld.c | 2 ++ elf/tst-audit21.c | 42 +++++++++++++++++++++++ elf/tst-auditmod21a.c | 80 +++++++++++++++++++++++++++++++++++++++++++ elf/tst-auditmod21b.c | 22 ++++++++++++ include/link.h | 2 ++ 8 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 elf/tst-audit21.c create mode 100644 elf/tst-auditmod21a.c create mode 100644 elf/tst-auditmod21b.c diff --git a/elf/Makefile b/elf/Makefile index 4636a2743a..587df12b3d 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -234,6 +234,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit19a \ tst-audit19b \ tst-audit20 \ + tst-audit21 \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -380,6 +381,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod19b \ tst-audit19bmod \ tst-auditmod20 \ + tst-auditmod21a \ + tst-auditmod21b \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1575,6 +1578,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd) $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so +$(objpfx)tst-audit21: $(shared-thread-library) +$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so +$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so +tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.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 73a852ad42..faba319e5c 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1055,6 +1055,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; } /* Load all audit modules. */ 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-auditmod21a.c b/elf/tst-auditmod21a.c new file mode 100644 index 0000000000..a0584f36e6 --- /dev/null +++ b/elf/tst-auditmod21a.c @@ -0,0 +1,80 @@ +/* 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; + +/* Defined tst-auditmod21b.so */ +extern __thread int tls_var2; +extern __thread int tls_var3; + +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; + + tls_var2 = 0x2; + if (tls_var3 != 0x20) + abort (); + tls_var3 = 0x40; + + 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/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c new file mode 100644 index 0000000000..550f858b1d --- /dev/null +++ b/elf/tst-auditmod21b.c @@ -0,0 +1,22 @@ +/* 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 + . */ + +#define tls_ie __attribute__ ((tls_model ("initial-exec"))) + +__thread int tls_var2 tls_ie; +__thread int tls_var3 tls_ie = 0x20; diff --git a/include/link.h b/include/link.h index 6a9f788d2b..ba4c588873 100644 --- a/include/link.h +++ b/include/link.h @@ -195,6 +195,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 Mon Nov 15 18:37:28 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: 47711 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 3E9D03857C4E for ; Mon, 15 Nov 2021 18:48:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3E9D03857C4E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002126; bh=MXKYb/fSxmsGmFAagNOnZKfEUgLTQwNSP0JoxkyzrJw=; 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=oitC6UOVg1WGS+tByuGqjpmmbxUrg69iRdaJMmqSxDpmdIZgalFiZH47YatKmEzNe O2r2KkNdqPnkeYd4wUKYLCkwga3DcypTclL4IYIgTJlclXRQD6Uw7UCpEWJViTdpv2 LMk80ZEP7bifml96cSx27t98ps6qxCMnRpHGsECs= 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 5EE003857C73 for ; Mon, 15 Nov 2021 18:38:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5EE003857C73 Received: by mail-ua1-x935.google.com with SMTP id n6so20339466uak.1 for ; Mon, 15 Nov 2021 10:38:04 -0800 (PST) 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=MXKYb/fSxmsGmFAagNOnZKfEUgLTQwNSP0JoxkyzrJw=; b=Pa+qNs9d03N+uUEQyClHDcUrothBYKFunIIdnbEzExCsHG+PwAOO75XVbjfyAqC4u5 zXFkyTlf6Mw3O4AVJWR6IeV9KwNyHQ3tCLnXmfX/nrezEwKdEwNh6ZNpItCkMk9tWuAd 7U2h7pXYbQIX6o+8u29I+z8Nyg4SM+1chq2jPvh3hcqEhLByTnCWRBAqUxCvpPeQvOOD LNEKTtJxt2a2A3oFIipQzJZk58Gfl5iHjG5YJdSu1KiaIXvOoDX0l8RqUUuzvxNCMGKh JS+Hke7hZv9OJV5cuZ0ad33/910VZmpAVdst+CD30olRjvJp7FOozj4OQ0lwjWkTeyVd Wrww== X-Gm-Message-State: AOAM531Zu+uB+DMVV4Bax+00b2X2jRspU0mNk7PAypoOZq/PxOguYCfT xKIU9RgpJoaD9gfCEg4BoJBSKO/4SWg/Ug== X-Google-Smtp-Source: ABdhPJzsOVcwSgiQk0xVAMGOlOnvHgLmukaW2wsg7bjlmsxgT42HnTGRhzITAY2yV8CPaGuK1HPRwQ== X-Received: by 2002:ab0:3ca0:: with SMTP id a32mr1359461uax.63.1637001483219; Mon, 15 Nov 2021 10:38:03 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:03 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 14/20] elf: Issue audit la_objopen() for vDSO Date: Mon, 15 Nov 2021 15:37:28 -0300 Message-Id: <20211115183734.531155-15-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 | 124 +++++++++++++++++++++++++++++++++++++++++++ elf/tst-auditmod22.c | 51 ++++++++++++++++++ include/dlfcn.h | 1 + 7 files changed, 199 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 587df12b3d..35e45d969e 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -235,6 +235,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit19b \ tst-audit20 \ tst-audit21 \ + tst-audit22 \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -383,6 +384,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod20 \ tst-auditmod21a \ tst-auditmod21b \ + tst-auditmod22 \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1583,6 +1585,9 @@ $(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so $(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.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 faba319e5c..55b4eb91f2 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1879,6 +1879,13 @@ dl_main (const ElfW(Phdr) *phdr, assert (i == npreloads); } +#ifdef NEED_DL_SYSINFO_DSO + /* Now that the audit modules are opened, call la_objopen() for the + vDSO. */ + if (GLRO(dl_sysinfo_map) != NULL) + _dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE, true); +#endif + /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD specified some libraries to load, these are inserted before the actual dependencies in the executable's searchlist for symbol resolution. */ diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h index 3f20578046..2b013d974a 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..f136f25a32 --- /dev/null +++ b/elf/tst-audit22.c @@ -0,0 +1,124 @@ +/* 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: %p\n", (void*) vdso_addr); + return 0; +} + +static uintptr_t +parse_address (const char *str) +{ + void *r; + TEST_COMPARE (sscanf (str, "%p\n", &r), 1); + return (uintptr_t) r; +} + +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); + + /* The respawned process should always print the vDSO address (otherwise it + will fails as unsupported). However, on some architectures the audit + module might see the vDSO with l_addr being 0, meaning a fixed mapping + (linux-gate.so). In this case we don't its value against AT_SYSINFO_EHDR + one. */ + uintptr_t vdso_process = 0; + bool vdso_audit_found = false; + uintptr_t 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: ")); + vdso_audit_found = true; + } + } + + TEST_COMPARE (vdso_audit_found, true); + if (vdso_audit != 0) + 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..8e05ce8cbb --- /dev/null +++ b/elf/tst-auditmod22.c @@ -0,0 +1,51 @@ +/* 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 + +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; +} + +unsigned int +la_version (unsigned int version) +{ + return LAV_CURRENT; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + /* The linux-gate.so is placed at a fixed address, thus l_addr being 0, + and it might be the value reported as the AT_SYSINFO_EHDR. */ + if (map->l_addr == 0 && startswith (map->l_name, "linux-gate.so")) + fprintf (stderr, "vdso found: %p\n", NULL); + else if (map->l_addr == getauxval (AT_SYSINFO_EHDR)) + fprintf (stderr, "vdso found: %p\n", (void*) 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 Mon Nov 15 18:37:29 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: 47712 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 7A87E3857C71 for ; Mon, 15 Nov 2021 18:49:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7A87E3857C71 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002168; bh=zalrArEzflFAZo2LG3BDFvI+Ei2zzI84iAlAFLSATuQ=; 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=K/+A1ccw4+ip/oEecfzvlIvn6/o5V98COyCP5XMN/S3h7yhbswzaOQrKA+xEE9GU3 g1Az3sAMLglaGzrkusrZM6Yoj2zcIK9Rgk2EL0cNbrfL/UawtiRSO0jqP/pGxiR4mM DRyWICYr9lsTXhX69vlPsqI1NpRg4z7fSJbaHesQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa30.google.com (mail-vk1-xa30.google.com [IPv6:2607:f8b0:4864:20::a30]) by sourceware.org (Postfix) with ESMTPS id 6DA203857805 for ; Mon, 15 Nov 2021 18:38:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6DA203857805 Received: by mail-vk1-xa30.google.com with SMTP id m19so4914104vko.12 for ; Mon, 15 Nov 2021 10:38:05 -0800 (PST) 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=zalrArEzflFAZo2LG3BDFvI+Ei2zzI84iAlAFLSATuQ=; b=xDqS2G/U53rlwnwNE2P1bo74tkN69SvQpm//CcTHP4Ss1/ZPsk6KtAX5Ejq2CDd/RA GUuR48GL4ooA3+x1ZtM8EV9G4W6zJ1piDkFruK5mvf228xSymfc7G4KbgaN8oP7bNnGw QgpSEMrE0FFt+X9HacbK3SB97QvTq7eSYxse9aHGqyZiwo+gWXi7WtOWe3XquuT/B92+ cFsXnTLd96RD5p58ukpOP25HC17DM2dDyIDSTgBoiDjsVnjCNuQU7DLq+u6XnY7eD+09 DBsHPdYfyYHn8ogzB5j2dpTJwvI9/PJtCov4+A6CjW/iEnFSQx0f2hzm9x8CmkiZ3a/A 9WEg== X-Gm-Message-State: AOAM533+JOQpsMakNpEw5LBhw4sjPibxEQHkGE/xvTRAz331UmGB5nm4 XEue/qF80n5ETvy48c3csJC58+QVH35pGw== X-Google-Smtp-Source: ABdhPJxA8jdxdahzMvicB1E06Qssff3dKnWwFZj7ZuGN2QAFuW0IVbLTEW8OVSZ/GSd6jJ4e3NR98w== X-Received: by 2002:a1f:e287:: with SMTP id z129mr61934771vkg.17.1637001484836; Mon, 15 Nov 2021 10:38:04 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:04 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 15/20] elf: Run constructors if executable has a soname of a dependency Date: Mon, 15 Nov 2021 15:37:29 -0300 Message-Id: <20211115183734.531155-16-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: John Mellor-Crummey Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The DSO constructor should not be ignored if the main executable has the SONAME set to a dependency. It fixes the case where (using the scripts/dso-ordering-test.py definition): {}->a->b->c;soname({})=c Where the constructors should return c>b>a>{}= 0); assert (nsid < GL(dl_nns)); + /* Special case: trying to map itself. An empty name correspond to + a NULL or "" argument for dlopen(), and it returns the head object + of the namespace. */ + 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) != 0 + || l->l_type == lt_executable)) continue; if (!_dl_name_match_p (name, l)) { diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def index 5f7f18ef27..2228910c0d 100644 --- a/elf/dso-sort-tests-1.def +++ b/elf/dso-sort-tests-1.def @@ -50,7 +50,10 @@ output: e>d>c>b>a>{}a->b->c;soname({})=c -output: b>a>{}b>a>{}a->b->c;soname({})=a +output: c>b>a>{} X-Patchwork-Id: 47713 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 5B56A3857C71 for ; Mon, 15 Nov 2021 18:50:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B56A3857C71 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002215; bh=H7Ghcy+voFRHN/tkRFuXxwnCNrCaGczbRbltMf8PtFI=; 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=JInfPKqRh29kemInD+5ga21Kpf1RTankX9VnLjVThx8MCQShjmO1g8hQ+HsTfZftk glH8tykFEE7Aw1ARDuH2phOPdr8OD7xEDqvY9C/xuZnaAOfZCEEh38Hd8p4rGG13By hby/atTWi1gBveEkKzd1V7DHIcZkQYxJYky3NR40= 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 386953857C63 for ; Mon, 15 Nov 2021 18:38:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 386953857C63 Received: by mail-ua1-x936.google.com with SMTP id l24so32634719uak.2 for ; Mon, 15 Nov 2021 10:38:07 -0800 (PST) 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=H7Ghcy+voFRHN/tkRFuXxwnCNrCaGczbRbltMf8PtFI=; b=WoDQ1n3H5pmWiGn4NiLdjbF5lq1WmekOJp230Itrb+QRYuUW01BTPr2QVhrxW0nDVh P7lrR4elg5PYWw5zeoO86WXAtwReC0wE1qIsptxasDkNe07KOEbFoLignff4HwsiNCpp FaQrZwQq1HRuG8hWk+GLGmEss106s20hVwwOoJnSiiNj8M3hD0eosoNyGLSP0sATMJXF 2p/js8Itqj+Gd4eGjBcQN/W2uu+/xpbqPZjwk+yReHnQBoKYrNMY2XQiLIMnybTXn4lu HkQs0l3AHwllCgjaDOGRnYZmEt9i/Tn7TrcZ3590tMBbIOBK3+EiUkY0MqzBH9jCNkXq uzuQ== X-Gm-Message-State: AOAM531GNrTPKO+iNsKbuJMmtnadfKoorJBF0+bm8cNrrf0bzyWeLLDi +l3h/oD2h4omBrTShUYudfAtoXhM5RxiOw== X-Google-Smtp-Source: ABdhPJxHKAbPEGPDdtEziRzM/6d540yO03svAZRYIpqJ/oRCuC1ZbKtGvtiTyXxouePRf9DnlxUmnQ== X-Received: by 2002:a05:6102:e82:: with SMTP id l2mr45446907vst.37.1637001486570; Mon, 15 Nov 2021 10:38:06 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:06 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 16/20] elf: Add main application on main_map l_name Date: Mon, 15 Nov 2021 15:37:30 -0300 Message-Id: <20211115183734.531155-17-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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-misc.c | 1 + elf/rtld.c | 6 +---- elf/tst-audit22.c | 4 +++ elf/tst-auditmod22.c | 8 ++++++ gmon/gmon.c | 10 ++++---- 10 files changed, 79 insertions(+), 19 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-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 55b4eb91f2..29a37f51d3 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1361,11 +1361,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; /* Set bit indicating this is the main program map. */ @@ -1431,6 +1426,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 f136f25a32..f5e16c69fe 100644 --- a/elf/tst-audit22.c +++ b/elf/tst-audit22.c @@ -94,6 +94,7 @@ do_test (int argc, char *argv[]) uintptr_t vdso_process = 0; bool vdso_audit_found = false; uintptr_t vdso_audit = 0; + bool mainapp_found = false; FILE *out = fmemopen (result.err.buffer, result.err.length, "r"); TEST_VERIFY (out != NULL); @@ -108,11 +109,14 @@ do_test (int argc, char *argv[]) vdso_audit = parse_address (buffer + strlen ("vdso found: ")); vdso_audit_found = true; } + else if (startswith (buffer, "mainapp found")) + mainapp_found = true; } TEST_COMPARE (vdso_audit_found, true); if (vdso_audit != 0) 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 8e05ce8cbb..687789ab34 100644 --- a/elf/tst-auditmod22.c +++ b/elf/tst-auditmod22.c @@ -21,6 +21,7 @@ #include #include #include +#include #include static inline bool @@ -47,5 +48,12 @@ la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) else if (map->l_addr == getauxval (AT_SYSINFO_EHDR)) fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr); + { + 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"); + } + return 0; } 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 Mon Nov 15 18:37:31 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: 47714 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 904D33858405 for ; Mon, 15 Nov 2021 18:50:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 904D33858405 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002257; bh=5XrrThdMmucm7iMn3D/XzfvpXx92tLu/d/C8218YCFM=; 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=uT/BVLe4FWnpLrIWNgIV5btn5W4Eld5u7sGjaWdaEgHUO4EJd4ts81FS03aHz5t// zmSs9Kq9exUMMUv8uKaYPTG60qwbvC3bJll9QL70SW2dRVJjLB4IMkhac0TESWeltS AH33v+2meGi+owBCRwcUpeKUE75xXcH/XKpA7Izg= 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 BCB7A3857C79 for ; Mon, 15 Nov 2021 18:38:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BCB7A3857C79 Received: by mail-ua1-x932.google.com with SMTP id w23so13989318uao.5 for ; Mon, 15 Nov 2021 10:38:08 -0800 (PST) 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=5XrrThdMmucm7iMn3D/XzfvpXx92tLu/d/C8218YCFM=; b=B3Jx8JVB9u/g5u0w7jXgZ/BH6Yg62QuQCPJ8/rrL3oG6YhDy3wB7v/m/ee686mcnUk 5LtAEvsMDxD4ZDJwqeRJkOtkriSdF/fVxF3m5LqeK+N4ADYTcr5GanatOxpXev+3Amb5 yphR1Ad+IrlV8daaR55ovk6/AEuOYYbzr9DACcejhed/48/aHSy+fzRlaYU0XN6ZZKkD qFb9KhJey0Tvtx/yLcGuG1Hl9NspE5hg4p4plPdZrK3XGIAgoDvqpSFAfNdvS+W1SQ4H Pgx9jrUdGiPfxKU1Wcj+EEtBPZRatee+L/+zCBrEHmvgEhaHtjuSBqivGsCq58wuIXb4 FH/g== X-Gm-Message-State: AOAM532UTcCoa0v/q39PmTjkaqrg492LvJkHE9K1K3g9KENsk0uAhSbo S4C1kJFfGFyfOCTMIEBpaqEjELZIvPgeJA== X-Google-Smtp-Source: ABdhPJzFL1aZZ2EjnfpUR75RGQBV5xDhKrPd3odG5ktAEUlHQQaHfXnrEU9xiXran3Td4W91OPJIJQ== X-Received: by 2002:a67:f516:: with SMTP id u22mr47148413vsn.47.1637001488172; Mon, 15 Nov 2021 10:38:08 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:07 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 17/20] elf: Add la_activity during application exit Date: Mon, 15 Nov 2021 15:37:31 -0300 Message-Id: <20211115183734.531155-18-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella 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 | 7 ++ elf/dl-fini.c | 9 +++ elf/tst-audit23.c | 173 +++++++++++++++++++++++++++++++++++++++++++ elf/tst-audit23mod.c | 23 ++++++ elf/tst-auditmod23.c | 68 +++++++++++++++++ 5 files changed, 280 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 35e45d969e..ee4daae0fc 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -236,6 +236,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit20 \ tst-audit21 \ tst-audit22 \ + tst-audit23 \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -385,6 +386,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod21a \ tst-auditmod21b \ tst-auditmod22 \ + tst-auditmod23 \ + tst-audit23mod \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1588,6 +1591,10 @@ tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.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 1720cfaeb8..7c5f2f0e40 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]; @@ -153,6 +157,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..c0070b3b00 --- /dev/null +++ b/elf/tst-audit23.c @@ -0,0 +1,173 @@ +/* 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 inline bool +is_name_vdso (const char *str) +{ + return startswith (str, "linux-gate") + || startswith (str, "linux-vdso"); +} + +static int +do_test (int argc, char *argv[]) +{ + /* We must have either: + - One our fource parameters left if called initially: + + path to ld.so optional + + "--library-path" optional + + the library path optional + + the application name */ + if (restart) + return handle_restart (); + + char *spargv[9]; + int i = 0; + for (; i < argc - 1; i++) + spargv[i] = argv[i + 1]; + spargv[i++] = (char *) "--direct"; + spargv[i++] = (char *) "--restart"; + spargv[i] = NULL; + + setenv ("LD_AUDIT", "tst-auditmod23.so", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr); + + + /* 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). + 6. vdso (optional and ignored). */ + enum { max_objs = 6 }; + struct la_obj_t + { + char *lname; + uintptr_t laddr; + Lmid_t lmid; + bool closed; + } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } }; + size_t nobjs = 0; + + 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) + { + /* la_objclose is not triggered by vDSO because glibc does not + unload it. */ + if (is_name_vdso (lname)) + continue; + if (nobjs == max_objs) + FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld", + lname, laddr, lmid); + objs[nobjs].lname = lname; + objs[nobjs].laddr = laddr; + objs[nobjs].lmid = lmid; + objs[nobjs].closed = false; + nobjs++; + } + 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..869afd372f --- /dev/null +++ b/elf/tst-auditmod23.c @@ -0,0 +1,68 @@ +/* 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 + +unsigned int +la_version (unsigned int version) +{ + 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) +{ + 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 Mon Nov 15 18:37: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: 47715 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 E5CBE3857809 for ; Mon, 15 Nov 2021 18:51:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E5CBE3857809 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002306; bh=iQ+ittWIBlhmcKN+2R7Pquv1TMx9m7KS9+HaElPSBNo=; 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=dif6nM18ylIt6PtjnyrLWki2Oix4dM4cgV+CDh8B5HgG+EUudCamb8RvNYqa6iD7q gVTWM3Rxd3pOv/0gCJPSTxQ0OkmXpu9gX/h+n1t+Sb+fgSFsfI4GeO6TbQSEXDIIwA QMJSYj764xHz1xXixUioiwM6X9bUM9zSxZijeDNQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa32.google.com (mail-vk1-xa32.google.com [IPv6:2607:f8b0:4864:20::a32]) by sourceware.org (Postfix) with ESMTPS id E6F12385802E for ; Mon, 15 Nov 2021 18:38:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E6F12385802E Received: by mail-vk1-xa32.google.com with SMTP id d130so9711091vke.0 for ; Mon, 15 Nov 2021 10:38:11 -0800 (PST) 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=iQ+ittWIBlhmcKN+2R7Pquv1TMx9m7KS9+HaElPSBNo=; b=lOJgEOf/dcxCkVM+m7tc7SFcKvLp4Bt5xX2g3L4WtLDdI6yWJDFg4jAqwpwFvARg67 dVUvZXctqSqFbDOFVqDVSk3vU67E5Hup3LSysmmHGLQbczXZcsd1BXeSNQFD4IuvxiDl bFastOULh8rbfqc761CTGQvhTi4z5n4/7GKzAMkPzjP31kINmvje1nfmDe5TBB7GKhNS TViJWw/CdTNZn8niNJK/DXD72pgmfh3X1av/0Pxdao0eOKBV8nYM8gAO4mGmoX1fO9d8 TtnNBmIaAZRYGKHrK8yf3BlAKBe5DRjxxI0EWxSOtzwnnwQccKCopQwqCGCDtQPW+i0p 6Hcg== X-Gm-Message-State: AOAM530eXRSmvv74vE+qEYkLwtttg+o1OgTRt97gbtVgiguUIY3QDUe+ XGDdfsStElyec8+3L7fI6UEtdRfvCsd/hw== X-Google-Smtp-Source: ABdhPJyQl0URwin/gR5saZCbLu1nKU3UGyTZ9kg1rBYg9Gm0lov74iA+QgRgWUacj75mAaanzKL+fQ== X-Received: by 2002:a05:6122:1812:: with SMTP id ay18mr62702106vkb.18.1637001489856; Mon, 15 Nov 2021 10:38:09 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:09 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 18/20] elf: Issue la_symbind() for bind-now (BZ #23734) Date: Mon, 15 Nov 2021 15:37:32 -0300 Message-Id: <20211115183734.531155-19-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 OPD (for lazy binding this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve). Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, powerpc64-linux-gnu. --- elf/Makefile | 86 ++++++++++++++++++++++ elf/dl-audit.c | 19 ++--- 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-audit25a.c | 127 ++++++++++++++++++++++++++++++++ elf/tst-audit25b.c | 128 +++++++++++++++++++++++++++++++++ elf/tst-audit25mod1.c | 30 ++++++++ elf/tst-audit25mod2.c | 30 ++++++++ elf/tst-audit25mod3.c | 22 ++++++ elf/tst-audit25mod4.c | 22 ++++++ elf/tst-auditmod24.h | 29 ++++++++ elf/tst-auditmod24a.c | 113 +++++++++++++++++++++++++++++ elf/tst-auditmod24b.c | 103 ++++++++++++++++++++++++++ elf/tst-auditmod24c.c | 3 + elf/tst-auditmod24d.c | 119 ++++++++++++++++++++++++++++++ elf/tst-auditmod25.c | 78 ++++++++++++++++++++ sysdeps/generic/dl-lookupcfg.h | 3 + sysdeps/generic/ldsodefs.h | 2 +- sysdeps/hppa/dl-lookupcfg.h | 3 + sysdeps/ia64/dl-lookupcfg.h | 3 + sysdeps/powerpc/dl-lookupcfg.h | 39 ++++++++++ 34 files changed, 1344 insertions(+), 30 deletions(-) create mode 100644 elf/tst-audit24a.c create mode 100644 elf/tst-audit24amod1.c create mode 100644 elf/tst-audit24amod2.c create mode 100644 elf/tst-audit24b.c create mode 100644 elf/tst-audit24bmod1.c create mode 100644 elf/tst-audit24bmod2.c create mode 100644 elf/tst-audit24c.c create mode 100644 elf/tst-audit24d.c create mode 100644 elf/tst-audit24dmod1.c create mode 100644 elf/tst-audit24dmod2.c create mode 100644 elf/tst-audit24dmod3.c create mode 100644 elf/tst-audit24dmod4.c create mode 100644 elf/tst-audit25a.c create mode 100644 elf/tst-audit25b.c create mode 100644 elf/tst-audit25mod1.c create mode 100644 elf/tst-audit25mod2.c create mode 100644 elf/tst-audit25mod3.c create mode 100644 elf/tst-audit25mod4.c create mode 100644 elf/tst-auditmod24.h create mode 100644 elf/tst-auditmod24a.c create mode 100644 elf/tst-auditmod24b.c create mode 100644 elf/tst-auditmod24c.c create mode 100644 elf/tst-auditmod24d.c create mode 100644 elf/tst-auditmod25.c create mode 100644 sysdeps/powerpc/dl-lookupcfg.h diff --git a/elf/Makefile b/elf/Makefile index ee4daae0fc..acce163078 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -237,6 +237,12 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit21 \ tst-audit22 \ tst-audit23 \ + tst-audit24a \ + tst-audit24b \ + tst-audit24c \ + tst-audit24d \ + tst-audit25a \ + tst-audit25b \ # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -388,6 +394,23 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod22 \ tst-auditmod23 \ tst-audit23mod \ + tst-auditmod24a \ + tst-audit24amod1 \ + tst-audit24amod2 \ + tst-auditmod24b \ + tst-audit24bmod1 \ + tst-audit24bmod2 \ + tst-auditmod24c \ + tst-auditmod24d \ + tst-audit24dmod1 \ + tst-audit24dmod2 \ + tst-audit24dmod3 \ + tst-audit24dmod4 \ + tst-auditmod25 \ + tst-audit25mod1 \ + tst-audit25mod2 \ + tst-audit25mod3 \ + tst-audit25mod4 \ # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. @@ -1595,6 +1618,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \ $(objpfx)tst-audit23mod.so tst-audit23-ARGS = -- $(host-test-program-cmd) +$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so +$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \ + $(objpfx)tst-audit24amod2.so +tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so +LDFLAGS-tst-audit24a = -Wl,-z,now + +$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so +$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \ + $(objpfx)tst-audit24bmod2.so +$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so +# The test check if a library without .gnu.version correctly calls the +# audit callbacks. So it uses an explicit link rule to avoid linking +# against libc.so. +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \ + -Wl,-z,now + $(call after-link,$@.new) + mv -f $@.new $@ +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1) +$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os + $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os + $(call after-link,$@.new) + mv -f $@.new $@ +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2) +tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so +LDFLAGS-tst-audit24b = -Wl,-z,now + +# Same as tst-audit24a, but tests LD_BIND_NOW +$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so +$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \ + $(objpfx)tst-audit24amod2.so +tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so +LDFLAGS-tst-audit24b = -Wl,-z,lazy + +$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so +$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \ + $(objpfx)tst-audit24dmod2.so +$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so +LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now +$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so +LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy +tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so +LDFLAGS-tst-audit24d = -Wl,-z,lazy + +$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so +$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \ + $(objpfx)tst-audit25mod2.so \ + $(objpfx)tst-audit25mod3.so \ + $(objpfx)tst-audit25mod4.so +$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so +LDFLAGS-tst-audit25mod1.so = -Wl,-z,now +$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so +LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy +tst-audit25a-ARGS = -- $(host-test-program-cmd) + +$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so +$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ + $(objpfx)tst-audit25mod2.so \ + $(objpfx)tst-audit25mod3.so \ + $(objpfx)tst-audit25mod4.so +LDFLAGS-tst-audit25b = -Wl,-z,now +tst-audit25b-ARGS = -- $(host-test-program-cmd) + # tst-sonamemove links against an older implementation of the library. LDFLAGS-tst-sonamemove-linkmod1.so = \ -Wl,--version-script=tst-sonamemove-linkmod1.map \ diff --git a/elf/dl-audit.c b/elf/dl-audit.c index c3569cb357..f080591596 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 @@ -219,6 +219,7 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, unsigned int flags = 0; struct audit_ifaces *afct = GLRO(dl_audit); + uintptr_t new_value = (uintptr_t) sym.st_value; for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) { /* XXX Check whether both DSOs must request action or only one */ @@ -229,16 +230,16 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, { if (afct->symbind != NULL) { - uintptr_t new_value = afct->symbind (&sym, - reloc_result->boundndx, - &l_state->cookie, - &result_state->cookie, - &flags, - strtab2 + defsym->st_name); + flags |= bindnow ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT : 0; + 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; + sym.st_value = bindnow + ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value; } } @@ -259,7 +260,7 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, } reloc_result->flags = flags; - *value = DL_FIXUP_ADDR_VALUE (sym.st_value); + DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value); } void diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 64a96c36e8..345809e3e2 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -234,9 +234,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)) @@ -285,8 +283,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) @@ -309,6 +305,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 9a38eea7cc..66945b57f8 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -146,7 +146,7 @@ _dl_fixup ( unsigned int init = atomic_load_acquire (&reloc_result->init); if (init == 0) { - _dl_audit_symbind (l, reloc_result, sym, &value, result); + _dl_audit_symbind (l, reloc_result, sym, &value, result, false); /* Store the result for later runs. */ if (__glibc_likely (! GLRO(dl_bind_not))) @@ -321,7 +321,7 @@ _dl_profile_fixup ( auditing libraries the possibility to change the value and tell us whether further auditing is wanted. */ if (defsym != NULL && GLRO(dl_naudit) > 0) - _dl_audit_symbind (l, reloc_result, defsym, &value, result); + _dl_audit_symbind (l, reloc_result, defsym, &value, result, false); #endif /* Store the result for later runs. */ diff --git a/elf/do-rel.h b/elf/do-rel.h index 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-audit25a.c b/elf/tst-audit25a.c new file mode 100644 index 0000000000..e3e7200f85 --- /dev/null +++ b/elf/tst-audit25a.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 is build with -Wl,-z,lazy and tst-audit25mod1 with + -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to + have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 0\n" + "la_symbind: tst_audit25mod1_func2 0\n" + "la_symbind: tst_audit25mod2_func1 0\n" + "la_symbind: tst_audit25mod4_func1 0\n" + "la_symbind: tst_audit25mod2_func2 0\n"); + + support_capture_subprocess_free (&result); + } + + { + setenv ("LD_BIND_NOW", "1", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit25a", 0, + sc_allow_stderr); + + /* With LD_BIND_NOW all symbols are expected to have + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution + order is done in breadth-first order. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod4_func1 1\n" + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 1\n" + "la_symbind: tst_audit25mod2_func1 1\n" + "la_symbind: tst_audit25mod1_func2 1\n" + "la_symbind: tst_audit25mod2_func2 1\n"); + + support_capture_subprocess_free (&result); + } + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c new file mode 100644 index 0000000000..d497b82d56 --- /dev/null +++ b/elf/tst-audit25b.c @@ -0,0 +1,128 @@ +/* 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_NOPLTENTER | LA_SYMB_NOPLTEXIT. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 1\n" + "la_symbind: tst_audit25mod2_func1 1\n" + "la_symbind: tst_audit25mod1_func2 1\n" + "la_symbind: tst_audit25mod2_func2 1\n" + "la_symbind: tst_audit25mod4_func1 0\n"); + + support_capture_subprocess_free (&result); + } + + { + setenv ("LD_BIND_NOW", "1", 0); + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit25a", 0, + sc_allow_stderr); + + /* With LD_BIND_NOW all symbols are expected to have + LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution + order is done in breadth-first order. */ + TEST_COMPARE_STRING (result.err.buffer, + "la_symbind: tst_audit25mod4_func1 1\n" + "la_symbind: tst_audit25mod3_func1 1\n" + "la_symbind: tst_audit25mod1_func1 1\n" + "la_symbind: tst_audit25mod2_func1 1\n" + "la_symbind: tst_audit25mod1_func2 1\n" + "la_symbind: tst_audit25mod2_func2 1\n"); + + support_capture_subprocess_free (&result); + } + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include 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-auditmod24.h b/elf/tst-auditmod24.h new file mode 100644 index 0000000000..621fd50364 --- /dev/null +++ b/elf/tst-auditmod24.h @@ -0,0 +1,29 @@ +/* Auxiliary functions for tst-audit24x. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _TST_AUDITMOD24_H +#define _TST_AUDITMOD24_H + +static void +check_symbind_flags (unsigned int flags) +{ + if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0) + abort (); +} + +#endif diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c new file mode 100644 index 0000000000..09d89269df --- /dev/null +++ b/elf/tst-auditmod24a.c @@ -0,0 +1,113 @@ +/* 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 +#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) + { + /* Check if bind-now symbols are advertised to not call the PLT + hooks. */ + check_symbind_flags (*flags); + + if (strcmp (symname, TEST_FUNC "mod1_func1") == 0) + return (uintptr_t) tst_func1; + else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0) + return sym->st_value; + abort (); + } + if (*defcook == AUDIT24MOD2_COOKIE + && (strcmp (symname, TEST_FUNC "mod2_func1") == 0)) + { + check_symbind_flags (*flags); + + return (uintptr_t) tst_func2; + } + + /* malloc functions. */ + return sym->st_value; + } + + abort (); +} diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c new file mode 100644 index 0000000000..dd3771ae5b --- /dev/null +++ b/elf/tst-auditmod24b.c @@ -0,0 +1,103 @@ +/* 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 +#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)) + { + check_symbind_flags (*flags); + return (uintptr_t) tst_func2; + } + } + + abort (); +} diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c new file mode 100644 index 0000000000..67e62c9d33 --- /dev/null +++ b/elf/tst-auditmod24c.c @@ -0,0 +1,3 @@ +#define TEST_NAME "tst-audit24c" +#define TEST_MOD "tst-audit24a" +#include "tst-auditmod24a.c" diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c new file mode 100644 index 0000000000..67e958f926 --- /dev/null +++ b/elf/tst-auditmod24d.c @@ -0,0 +1,119 @@ +/* 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; +} + +#include + +#if __ELF_NATIVE_CLASS == 64 +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#else +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, + uintptr_t *refcook, uintptr_t *defcook, + unsigned int *flags, const char *symname) +#endif +{ + if (*refcook == AUDIT24_COOKIE) + { + if (*defcook == AUDIT24MOD1_COOKIE) + { + if (strcmp (symname, "tst_audit24dmod1_func1") == 0) + return (uintptr_t) tst_audit24dmod1_func1; + else if (strcmp (symname, "tst_audit24dmod1_func2") == 0) + return sym->st_value; + abort (); + } + if (*defcook == AUDIT24MOD2_COOKIE + && (strcmp (symname, "tst_audit24dmod2_func1") == 0)) + return (uintptr_t) tst_audit24dmod2_func1; + + /* malloc functions. */ + return sym->st_value; + } + else if (*refcook == AUDIT24MOD1_COOKIE) + { + if (*defcook == AUDIT24MOD3_COOKIE + && strcmp (symname, "tst_audit24dmod3_func1") == 0) + { + check_symbind_flags (*flags); + + return (uintptr_t) tst_audit24dmod3_func1; + } + } + + abort (); +} diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c new file mode 100644 index 0000000000..bfdeadace5 --- /dev/null +++ b/elf/tst-auditmod25.c @@ -0,0 +1,78 @@ +/* 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 & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0); + return sym->st_value; +} diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h index c038c31ce6..a15fd32771 100644 --- a/sysdeps/generic/dl-lookupcfg.h +++ b/sysdeps/generic/dl-lookupcfg.h @@ -26,3 +26,6 @@ #define DL_FIXUP_VALUE_CODE_ADDR(value) (value) #define DL_FIXUP_VALUE_ADDR(value) (value) #define DL_FIXUP_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = st_value; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index d419a62dbd..a73859d16e 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1410,7 +1410,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/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h index a9a927f26c..f376965600 100644 --- a/sysdeps/hppa/dl-lookupcfg.h +++ b/sysdeps/hppa/dl-lookupcfg.h @@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map); #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip) #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = *(struct fdesc *) (st_value) diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h index 58ca32424b..2b8b2fa5db 100644 --- a/sysdeps/ia64/dl-lookupcfg.h +++ b/sysdeps/ia64/dl-lookupcfg.h @@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map); #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = *(struct fdesc *) (st_value) diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h new file mode 100644 index 0000000000..43fc94a7f6 --- /dev/null +++ b/sysdeps/powerpc/dl-lookupcfg.h @@ -0,0 +1,39 @@ +/* Configuration of lookup functions. PowerPC version. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define DL_FIXUP_VALUE_TYPE ElfW(Addr) +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) +#define DL_FIXUP_VALUE_ADDR(value) (value) +#define DL_FIXUP_ADDR_VALUE(addr) (addr) +#if __WORDSIZE == 64 && _CALL_ELF == 1 +/* We need to correctly set the audit modules value for bind-now. */ +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \ + (((Elf64_FuncDesc *)(addr))->fd_func) +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + ({ \ + Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value); \ + opd->fd_func = (st_value); \ + if ((new_value) != (uintptr_t) (st_value)) \ + opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc; \ + }) +#else +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr) +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \ + (*value) = st_value; +#endif From patchwork Mon Nov 15 18:37: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: 47716 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 3E1D03858031 for ; Mon, 15 Nov 2021 18:52:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3E1D03858031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002357; bh=0quol1ODt0/l6+lval1MS/dPrk2birfA+1Vg86G0l90=; 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=yLOaMMd2LbssrLMENUd2/Ipjpq1h+pR0RU5KjobMLK4fGY7q9XV5AmWAAFz1N0F9U UJ9wQIpR0MUSEwYUCkR7pLPOcC3Gbr0xgUf5ZTY8jVdLzgPKrh9IAK6lwlwoNj5Mag 9U+q4+N7OMc1Nxo7UaIehQsin0/sIUaHXKD4EOpc= 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 C6C983857C7A for ; Mon, 15 Nov 2021 18:38:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C6C983857C7A Received: by mail-ua1-x933.google.com with SMTP id az37so36890848uab.13 for ; Mon, 15 Nov 2021 10:38:16 -0800 (PST) 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=0quol1ODt0/l6+lval1MS/dPrk2birfA+1Vg86G0l90=; b=0pI9ndH3269qyCN9MB3kZymeg+l6dWWJ4XE8ZexopfJhikWYHqNauN4i9uVNYKDbur 9NIj/YmsxCoJGZYvBSa28zaL/tBfIeX1nlTAKwTBjyi7qAvUfWbWEoVt06Iw4kG+q0+J BDQmCWjoNFjAeGUZsbE+ZAojUtqe7XKMB3L6MWaCTd27Q8GtPzwOYTfZVKLArHHMMrne n+feoKMaZb28st4AaoD3KeLpGFERhLQmO7YyOtNlDoDsp+HMfoh8Odl+6LBfMAIc8HHs iAu7OJNwWKhC+Pc0U271z875URMxevkSNvMelvkW0SicTTR813nRfaDoRy8sonI1mSYH BMGg== X-Gm-Message-State: AOAM53378R+lf8VmtroqpU9VUqIA//8DnlMYS0FllL+puyKHr12scvUn jMUBGc41vA5bPw+/RlYdDBnUXHGiFgR4ng== X-Google-Smtp-Source: ABdhPJymnlo6vF1nqQkpF59YSpISt7Rhwnl1ORjSY2yP5gXhJtSx7z6uTtxdsEYtqHgTn4G2Cq+SEA== X-Received: by 2002:a67:af0a:: with SMTP id v10mr46243832vsl.35.1637001491578; Mon, 15 Nov 2021 10:38:11 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:11 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 19/20] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Date: Mon, 15 Nov 2021 15:37:33 -0300 Message-Id: <20211115183734.531155-20-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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 29a37f51d3..1a13ae6314 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -990,10 +990,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 Mon Nov 15 18:37: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: 47717 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 15380385781E for ; Mon, 15 Nov 2021 18:53:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 15380385781E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637002405; bh=XkmjwB9C3eLrLTlDUPgOBa5KMVDcvrnKqrSBJ+huXQM=; 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=BpLPVfBagtJI1ZzhYwq7DjyBPUMtL3YQ0u8txZVSHmiRz0Hy3sfhzr+niomu03/hU i0zr7PvnQ6kueE9jJ9nBggsRcJrPCp+zQ0delCjUWNHuSqrYr+kloWIIvbX9m3oOLN oObNkKjYi436QwoJtyJH9zoGnsu7RBom07wfMlpk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa35.google.com (mail-vk1-xa35.google.com [IPv6:2607:f8b0:4864:20::a35]) by sourceware.org (Postfix) with ESMTPS id 99D4E3858433 for ; Mon, 15 Nov 2021 18:38:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 99D4E3858433 Received: by mail-vk1-xa35.google.com with SMTP id b192so9697644vkf.3 for ; Mon, 15 Nov 2021 10:38:18 -0800 (PST) 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=XkmjwB9C3eLrLTlDUPgOBa5KMVDcvrnKqrSBJ+huXQM=; b=GeqGPNQ/l6qhS/DEL03U/gjKWyQJCh2pxceb0ooxJwnfaXU4U7McaI+uxE40EtlN97 Wp6ITfSV3ZE9+urLLatU8v7ycHgXvtcNwWxEG56QTVoBOv5RAOoBZ01qXaiMwbw8EGxV Jka1djPU2+0fKhHnWTaryZBYjYRQvMerfzyELEoL7U/j4GOLKnhMlXsHz22dJmDmvlN0 RcVc+xdRm6AGugXiRuDC57vy3UridYWE7g9BduqvH2BNpvvc5lrBBUiOG/0koyJfjJQS dkkYj0ITtyfsWeZN1t+pcT0NXJvKsSn+xWKkXCvQB32SS/ljkOY2ifxmI89neGbJ7Xqu wKMA== X-Gm-Message-State: AOAM533Z2xLFAorHTAWNUggi7P1rA38x4+OtpqGl/ylYk1NvYGHEQoUd 7mHeNsZ6IuVHJAWN0SOJKHT8pOhy+oGuKg== X-Google-Smtp-Source: ABdhPJyeb8eb3WE2h7Bknm+sT+mUXZmRZ7/Hl3qTrMgD+/eoULFHJuflASGeKrahalSNoWOARWe9TQ== X-Received: by 2002:a1f:c9c2:: with SMTP id z185mr19898150vkf.26.1637001496964; Mon, 15 Nov 2021 10:38:16 -0800 (PST) Received: from birita.. ([2804:431:c7ca:66dc:13f5:e2fb:5a0d:90]) by smtp.gmail.com with ESMTPSA id e7sm8976565vkn.20.2021.11.15.10.38.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 10:38:16 -0800 (PST) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v6 20/20] elf: Add SVE support for aarch64 rtld-audit Date: Mon, 15 Nov 2021 15:37:34 -0300 Message-Id: <20211115183734.531155-21-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211115183734.531155-1-adhemerval.zanella@linaro.org> References: <20211115183734.531155-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. --- elf/do-rel.h | 6 +- elf/dynamic-link.h | 26 ++- 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 | 299 ++++++++++++++++++++++++- 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(+), 92 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 f619615e5c..d1e83d8b8c 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 @@ -78,7 +80,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; } \ @@ -120,6 +123,7 @@ 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, \ + do_profile, \ skip_ifunc); \ } while (0) @@ -131,19 +135,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 @@ -152,8 +158,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..0aee1fbf3d 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] @@ -339,5 +342,299 @@ _dl_runtime_profile: cfi_endproc .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 */ + +#endif /* !PROF */ 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 4ecdde4355..b747f5cc3b 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);