From patchwork Fri Feb 24 16:53:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stas Sergeev X-Patchwork-Id: 65605 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 E06D23857C45 for ; Fri, 24 Feb 2023 16:54:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E06D23857C45 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677257677; bh=nZihGjoaGJvHThZq1CM+FMCZNvKR6LheeR/xgcK1we4=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=GEJZ524POgaPFw7birp1hlA+qAc3U0HUZIj4fnFvwL/I0NLPc2orD8++cvxCPY+hV meLg78hulmr+DUSt5x65NJ80XlW2X3YAvrvVrF4TgJaKqIwi9AVBI9dnxl/nGrgOP5 QekUQGzkuWGMQs6mt7t5cHuoRiiuXPFa4BmAw9r4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward101o.mail.yandex.net (forward101o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::601]) by sourceware.org (Postfix) with ESMTPS id 5ED6D385840F for ; Fri, 24 Feb 2023 16:54:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5ED6D385840F Received: from sas1-61ab5dc724a3.qloud-c.yandex.net (sas1-61ab5dc724a3.qloud-c.yandex.net [IPv6:2a02:6b8:c08:162d:0:640:61ab:5dc7]) by forward101o.mail.yandex.net (Yandex) with ESMTP id DB470369BE01 for ; Fri, 24 Feb 2023 19:54:09 +0300 (MSK) Received: by sas1-61ab5dc724a3.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id 7sTr1tFbZqM1-58jGjhiH; Fri, 24 Feb 2023 19:54:09 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 1/2] elf/dl-open: fix audit wrt RTLD_NOLOAD [BZ #30127] Date: Fri, 24 Feb 2023 21:53:59 +0500 Message-Id: <20230224165400.3417104-2-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230224165400.3417104-1-stsp2@yandex.ru> References: <20230224165400.3417104-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: Stas Sergeev Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Currently dlmopen() does not allow to load objects into an audit namespace. But the RTLD_NOLOAD case was forgotten, so the too restrictive check prevents even getting a handle for an objects in an audit namespace. This patch fixes the problem by relaxing a check in case of RTLD_NOLOAD. Test-case on x86_64 revealed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-open.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elf/dl-open.c b/elf/dl-open.c index 91a2d8a538..c7ce0396d3 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -864,7 +864,8 @@ no more namespaces available for dlmopen()")); DL_NNS is 1 and so any NSID != 0 is invalid. */ || DL_NNS == 1 || GL(dl_ns)[nsid]._ns_nloaded == 0 - || GL(dl_ns)[nsid]._ns_loaded->l_auditing)) + || (GL(dl_ns)[nsid]._ns_loaded->l_auditing && + !(mode & RTLD_NOLOAD)))) _dl_signal_error (EINVAL, file, NULL, N_("invalid target namespace in dlmopen()")); From patchwork Fri Feb 24 16:54:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stas Sergeev X-Patchwork-Id: 65606 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 8F12E385DC3C for ; Fri, 24 Feb 2023 16:55:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8F12E385DC3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677257721; bh=4H6m84T8zwpwjBl2HoT2GiRju/TsMtC70fif6QOU6KM=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=R3SUDLkvQ/AL7d+/QSRRsCbFfyvaPlOaQe2qjTHl/5qfgyHha7g+P8KeYyeU67YYY WhQCWUEKCNqgDz0/masksNI6290R58Gb72TGXitx63RLDiOyepNpr3pdQP3Y5LWKF3 TRihVkCCVhHHXOYI1A7Kp7XukWIpYy0m7MLti8PM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward107o.mail.yandex.net (forward107o.mail.yandex.net [37.140.190.210]) by sourceware.org (Postfix) with ESMTPS id C18AA3858284 for ; Fri, 24 Feb 2023 16:54:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C18AA3858284 Received: from sas1-61ab5dc724a3.qloud-c.yandex.net (sas1-61ab5dc724a3.qloud-c.yandex.net [IPv6:2a02:6b8:c08:162d:0:640:61ab:5dc7]) by forward107o.mail.yandex.net (Yandex) with ESMTP id 554636AF970C for ; Fri, 24 Feb 2023 19:54:11 +0300 (MSK) Received: by sas1-61ab5dc724a3.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id 7sTr1tFbZqM1-FduHOHBQ; Fri, 24 Feb 2023 19:54:10 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 2/2] dlfcn,elf: impl dlload_audit_module [BZ #30127] Date: Fri, 24 Feb 2023 21:54:00 +0500 Message-Id: <20230224165400.3417104-3-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230224165400.3417104-1-stsp2@yandex.ru> References: <20230224165400.3417104-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, SPF_HELO_NONE, SPF_PASS, TXREP, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: Stas Sergeev Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This patch is an impl of dlload_audit_module() function discussed in BZ #30127, and the test-case for it, called tst-loadaudit. It checks the loading of audit module at run-time and makes sure no "unrecognized" cookie is passed to the module call-backs. dlload_audit_module (const char *file, int flags) "file" is a module file name "flags" are reserved for future use. As mentioned in BZ #30134, audit module list was in RELRO so this patch makes it writable. To not compromise the hardening, several call-backs are disabled for dynamically loaded modules. Namely symbind, pltenter and pltexit. They have to be disabled also because the dynamically loaded audit module cannot interract with any object loaded before it, which is possible in case of these 3 call-backs. Test-suite run on x86_64 revealed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 4 +- dlfcn/Versions | 3 + dlfcn/dlaudit.c | 62 ++++++ elf/Makefile | 6 + elf/dl-audit.c | 47 +++-- elf/dl-fini.c | 2 +- elf/dl-load.c | 7 +- elf/dl-object.c | 4 +- elf/dl-reloc.c | 4 +- elf/dl-runtime.c | 2 +- elf/dl-sym-post.h | 2 +- elf/do-rel.h | 4 +- elf/rtld.c | 64 ++++-- elf/tst-dynauditmod.c | 190 ++++++++++++++++++ elf/tst-loadaudit.c | 138 +++++++++++++ include/link.h | 1 + manual/dynlink.texi | 1 + sysdeps/generic/ldsodefs.h | 11 +- sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 53 files changed, 535 insertions(+), 52 deletions(-) create mode 100644 dlfcn/dlaudit.c create mode 100644 elf/tst-dynauditmod.c create mode 100644 elf/tst-loadaudit.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 1fa7fea1ef..68f6916d0a 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -44,8 +44,8 @@ install-lib-ldscripts = libdl.so $(inst_libdir)/libdl.so: ifeq ($(build-shared),yes) -routines += dlopenold -shared-only-routines := dlopenold +routines += dlopenold dlaudit +shared-only-routines := dlopenold dlaudit endif ifeq (yes,$(build-shared)) diff --git a/dlfcn/Versions b/dlfcn/Versions index cc34eb824d..30145316d1 100644 --- a/dlfcn/Versions +++ b/dlfcn/Versions @@ -28,6 +28,9 @@ libc { dlsym; dlvsym; } + GLIBC_2.38 { + dlload_audit_module; + } GLIBC_PRIVATE { __libc_dlerror_result; _dlerror_run; diff --git a/dlfcn/dlaudit.c b/dlfcn/dlaudit.c new file mode 100644 index 0000000000..b124bbf932 --- /dev/null +++ b/dlfcn/dlaudit.c @@ -0,0 +1,62 @@ +/* Load an audit module at run time. + Copyright (C) 1995-2023 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 + +struct dlload_am_args +{ + /* The arguments for dlload_am_doit. */ + const char *file; + int flags; + /* The return value of dlload_am_doit. */ + void *new; +}; + +static void +dlload_am_doit (void *a) +{ + struct dlload_am_args *args = (struct dlload_am_args *) a; + + if (args->flags) + _dl_signal_error (0, NULL, NULL, _("invalid flags parameter")); + + args->new = GLRO(dlload_audit_module) (args->file, args->flags); +} + +static void * +dlload_am_implementation (const char *file, int flags) +{ + struct dlload_am_args args; + args.file = file; + args.flags = flags; + + return _dlerror_run (dlload_am_doit, &args) ? NULL : args.new; +} + +void * +___dlload_audit_module (const char *file, int flags) +{ + return dlload_am_implementation (file, flags); +} +versioned_symbol (libc, ___dlload_audit_module, dlload_audit_module, + GLIBC_2_38); diff --git a/elf/Makefile b/elf/Makefile index 2fc6391183..c73103c84a 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -821,6 +821,7 @@ modules-names += \ tst-deep1mod1 \ tst-deep1mod2 \ tst-deep1mod3 \ + tst-dynauditmod \ tst-dl_find_object-mod1 \ tst-dl_find_object-mod2 \ tst-dl_find_object-mod3 \ @@ -1055,6 +1056,7 @@ ifeq (yes,$(build-shared)) tests += \ tst-ifunc-fault-bindnow \ tst-ifunc-fault-lazy \ + tst-loadaudit \ # tests # Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8. tests-internal += \ @@ -2349,6 +2351,10 @@ $(objpfx)tst-audit28.out: $(objpfx)tst-auditmod28.so $(objpfx)tst-auditmod28.so: $(libsupport) tst-audit28-ENV = LD_AUDIT=$(objpfx)tst-auditmod28.so +$(objpfx)tst-loadaudit.out: $(objpfx)tst-dynauditmod.so \ + $(objpfx)tst-audit18mod.so +tst-loadaudit-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 00e794aa26..0770bd52b2 100644 --- a/elf/dl-audit.c +++ b/elf/dl-audit.c @@ -27,8 +27,8 @@ 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) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->activity != NULL) afct->activity (&link_map_audit_state (l, cnt)->cookie, action); @@ -43,8 +43,7 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action) does not give us a way to signal LA_ACT_CONSISTENT for it because the first loaded module is used to identify the namespace. */ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded; - if (__glibc_likely (GLRO(dl_naudit) == 0) - || head == NULL || head->l_auditing) + if (__glibc_likely (head == NULL || head->l_naudit == 0 || head->l_auditing)) return; _dl_audit_activity_map (head, action); @@ -56,8 +55,8 @@ _dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code) if (l == NULL || l->l_auditing || code == 0) return name; - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->objsearch != NULL) { @@ -75,11 +74,11 @@ _dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code) void _dl_audit_objopen (struct link_map *l, Lmid_t nsid) { - if (__glibc_likely (GLRO(dl_naudit) == 0)) + if (__glibc_likely (l->l_naudit == 0)) return; - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->objopen != NULL) { @@ -95,12 +94,12 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid) void _dl_audit_objclose (struct link_map *l) { - if (__glibc_likely (GLRO(dl_naudit) == 0) + if (__glibc_likely (l->l_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) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->objclose != NULL) { @@ -116,11 +115,11 @@ _dl_audit_objclose (struct link_map *l) void _dl_audit_preinit (struct link_map *l) { - if (__glibc_likely (GLRO(dl_naudit) == 0)) + if (__glibc_likely (l->l_naudit == 0)) return; - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->preinit != NULL) afct->preinit (&link_map_audit_state (l, cnt)->cookie); @@ -145,8 +144,8 @@ _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value, 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 audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { struct auditstate *match_audit = link_map_audit_state (l, cnt); struct auditstate *result_audit = link_map_audit_state (result, cnt); @@ -212,9 +211,9 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result, const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]); unsigned int flags = 0; - struct audit_ifaces *afct = GLRO(dl_audit); + struct audit_ifaces *afct = GL(dl_audit); uintptr_t new_value = (uintptr_t) sym.st_value; - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { /* XXX Check whether both DSOs must request action or only one */ struct auditstate *l_state = link_map_audit_state (l, cnt); @@ -267,7 +266,7 @@ _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 + if (l->l_naudit == 0 || (reloc_result->enterexit & LA_SYMB_NOPLTENTER)) return; @@ -290,8 +289,8 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result, /* 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) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->ARCH_LA_PLTENTER != NULL && (reloc_result->enterexit @@ -363,8 +362,8 @@ _dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg, 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) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < l->l_naudit; ++cnt) { if (afct->ARCH_LA_PLTEXIT != NULL && (reloc_result->enterexit diff --git a/elf/dl-fini.c b/elf/dl-fini.c index 9acb64f47c..a96f769953 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -129,7 +129,7 @@ _dl_fini (void) } #ifdef SHARED - if (! do_audit && GLRO(dl_naudit) > 0) + if (! do_audit && GL(dl_naudit) > 0) { do_audit = 1; goto again; diff --git a/elf/dl-load.c b/elf/dl-load.c index fcb39a78d4..720324ccfb 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1032,6 +1032,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l->l_addr = l->l_real->l_addr; l->l_ld = l->l_real->l_ld; + /* Do not call audit when this lm closes. */ + l->l_naudit = 0; + /* No need to bump the refcount of the real object, ld.so will never be unloaded. */ __close_nocancel (fd); @@ -1607,7 +1610,7 @@ open_verify (const char *name, int fd, #ifdef SHARED /* Give the auditing libraries a chance. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) + if (__glibc_unlikely (GL(dl_naudit) > 0)) { const char *original_name = name; name = _dl_audit_objsearch (name, loader, whatcode); @@ -2001,7 +2004,7 @@ _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)) + if (__glibc_unlikely (GL(dl_naudit) > 0)) { const char *before = name; name = _dl_audit_objsearch (name, loader, LA_SER_ORIG); diff --git a/elf/dl-object.c b/elf/dl-object.c index f1f2ec956c..497c57154a 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -77,7 +77,7 @@ _dl_new_object (char *realname, const char *libname, int type, naudit = DL_NNS; } else - naudit = GLRO (dl_naudit); + naudit = GL (dl_naudit); #endif size_t libname_len = strlen (libname) + 1; @@ -136,6 +136,8 @@ _dl_new_object (char *realname, const char *libname, int type, new->l_ns = nsid; #ifdef SHARED + /* GL(dl_naudit) is a current value and naudit is maximum value. */ + new->l_naudit = GL (dl_naudit); for (unsigned int cnt = 0; cnt < naudit; ++cnt) /* No need to initialize bindflags due to calloc. */ link_map_audit_state (new, cnt)->cookie = (uintptr_t) new; diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 1d558c1e0c..8aedbc0d96 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -222,8 +222,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], /* If we are auditing, install the same handlers we need for profiling. */ if ((reloc_mode & __RTLD_AUDIT) == 0) { - struct audit_ifaces *afct = GLRO(dl_audit); - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + struct audit_ifaces *afct = GL(dl_audit); + for (unsigned int cnt = 0; cnt < GL(dl_naudit); ++cnt) { /* Profiling is needed only if PLT hooks are provided. */ if (afct->ARCH_LA_PLTENTER != NULL diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index d35a725415..672d6fb702 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -313,7 +313,7 @@ _dl_profile_fixup ( /* 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. */ - if (defsym != NULL && GLRO(dl_naudit) > 0) + if (defsym != NULL && GL(dl_naudit) > 0) _dl_audit_symbind (l, reloc_result, defsym, &value, result); #endif diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h index 5623d63ac8..0cc50349ca 100644 --- a/elf/dl-sym-post.h +++ b/elf/dl-sym-post.h @@ -50,7 +50,7 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value, /* 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. */ - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) + if (__glibc_unlikely (GL(dl_naudit) > 0)) { if (match == NULL) match = _dl_sym_find_caller_link_map (caller); diff --git a/elf/do-rel.h b/elf/do-rel.h index 7e1cc4452a..22b5d566eb 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -148,7 +148,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], skip_ifunc); #if defined SHARED if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT - && GLRO(dl_naudit) > 0) + && GL(dl_naudit) > 0) { struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, rversion, @@ -193,7 +193,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], skip_ifunc); # if defined SHARED if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT - && GLRO(dl_naudit) > 0) + && GL(dl_naudit) > 0) { struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, diff --git a/elf/rtld.c b/elf/rtld.c index f82fbeb132..863b5a500b 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -151,6 +151,10 @@ static const char *audit_list_next (struct audit_list *); /* Initialize *STATE with the defaults. */ static void dl_main_state_init (struct dl_main_state *state); +/* Loads audit module. */ +static void * +_dlload_audit_module (const char *name, int flags); + /* Process all environments variables the dynamic linker must recognize. Since all of them start with `LD_' we are a bit smarter while finding all the entries. */ @@ -272,7 +276,7 @@ audit_list_next (struct audit_list *list) } } -/* Count audit modules before they are loaded so GLRO(dl_naudit) +/* Count audit modules before they are loaded so GL(dl_naudit) is not yet usable. */ static size_t audit_list_count (struct audit_list *list) @@ -375,6 +379,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro = ._dl_error_free = _dl_error_free, ._dl_tls_get_addr_soft = _dl_tls_get_addr_soft, ._dl_libc_freeres = __rtld_libc_freeres, + ._dlload_audit_module = _dlload_audit_module, }; /* If we would use strong_alias here the compiler would see a non-hidden definition. This would undo the effect of the previous @@ -930,8 +935,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", } /* Load one audit module. */ -static void -load_audit_module (const char *name, struct audit_ifaces **last_audit) +static void * +_load_audit_module (const char *name, const void *caller_dlopen, + struct audit_ifaces **last_audit) { int original_tls_idx = GL(dl_tls_max_dtv_idx); @@ -946,7 +952,7 @@ load_audit_module (const char *name, struct audit_ifaces **last_audit) if (__glibc_unlikely (err_str != NULL)) { report_audit_module_load_error (name, err_str, malloced); - return; + return NULL; } struct lookup_args largs; @@ -957,7 +963,7 @@ load_audit_module (const char *name, struct audit_ifaces **last_audit) { unload_audit_module (dlmargs.map, original_tls_idx); report_audit_module_load_error (name, err_str, malloced); - return; + return NULL; } unsigned int (*laversion) (unsigned int) = largs.result; @@ -977,7 +983,7 @@ load_audit_module (const char *name, struct audit_ifaces **last_audit) file=%s [%lu]; audit interface function la_version returned zero; ignored.\n", dlmargs.map->l_name, dlmargs.map->l_ns); unload_audit_module (dlmargs.map, original_tls_idx); - return; + return NULL; } if (!_dl_audit_check_version (lav)) @@ -986,7 +992,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n", ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n", name, lav, LAV_CURRENT); unload_audit_module (dlmargs.map, original_tls_idx); - return; + return NULL; } enum { naudit_ifaces = 8 }; @@ -1032,19 +1038,53 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); /* Now append the new auditing interface to the list. */ newp->ifaces.next = NULL; if (*last_audit == NULL) - *last_audit = GLRO(dl_audit) = &newp->ifaces; + *last_audit = GL(dl_audit) = &newp->ifaces; else *last_audit = (*last_audit)->next = &newp->ifaces; /* The dynamic linker link map is statically allocated, so the cookie in _dl_new_object has not happened. */ - link_map_audit_state (&GL (dl_rtld_map), GLRO (dl_naudit))->cookie + link_map_audit_state (&GL (dl_rtld_map), GL (dl_naudit))->cookie = (intptr_t) &GL (dl_rtld_map); - ++GLRO(dl_naudit); + ++GL(dl_naudit); /* Mark the DSO as being used for auditing. */ dlmargs.map->l_auditing = 1; + return dlmargs.map; +} + +static void +load_audit_module (const char *name, struct audit_ifaces **last_audit) +{ + if (_load_audit_module (name, dl_main, last_audit)) + { + struct link_map *l; + + /* Global audit module can audit all existing objects. */ + for (l = GL(dl_ns)[LM_ID_BASE]._ns_loaded; l; l = l->l_next) + l->l_naudit++; + } +} + +static void * +_dlload_audit_module (const char *name, int flags) +{ + struct link_map *l; + struct audit_ifaces *last_audit = GL(dl_audit); + + /* Find last audit list entry. */ + while (last_audit && last_audit->next) + last_audit = last_audit->next; + l = _load_audit_module (name, _dlload_audit_module, &last_audit); + if (l) + { + /* These are not allowed for dynamically-loaded auditors. */ + last_audit->symbind = NULL; + last_audit->ARCH_LA_PLTENTER = NULL; + last_audit->ARCH_LA_PLTEXIT = NULL; + } + return l; } /* Load all audit modules. */ @@ -1063,7 +1103,7 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list) /* Notify audit modules of the initially loaded modules (the main program and the dynamic linker itself). */ - if (GLRO(dl_naudit) > 0) + if (GL(dl_naudit) > 0) { _dl_audit_objopen (main_map, LM_ID_BASE); _dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE); @@ -1822,7 +1862,7 @@ dl_main (const ElfW(Phdr) *phdr, /* The count based on audit strings may overestimate the number of audit modules that got loaded, but not underestimate. */ - assert (GLRO(dl_naudit) <= naudit); + assert (GL(dl_naudit) <= naudit); } /* Keep track of the currently loaded modules to count how many diff --git a/elf/tst-dynauditmod.c b/elf/tst-dynauditmod.c new file mode 100644 index 0000000000..322e9ae4c7 --- /dev/null +++ b/elf/tst-dynauditmod.c @@ -0,0 +1,190 @@ +/* Audit mod for dlload_audit_module. + Copyright (C) 2021-2023 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 + +/* la_objopen() sets the cookie to this value. Other call-backs check + * the value to see if la_objopen() was not somehow skipped. */ +#define TST_COOKIE_VAL 12 + +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__); + assert (*cookie == TST_COOKIE_VAL); + return (char *) name; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + struct link_map *map = (void *) *cookie; + fprintf (stderr, "%s\n", __func__); + if (*cookie != TST_COOKIE_VAL) + fprintf (stderr, "%s\n", map->l_name); + *cookie = TST_COOKIE_VAL; +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) +{ + fprintf (stderr, "%s\n", __func__); + fprintf (stderr, "%s\n", map->l_name); + *cookie = TST_COOKIE_VAL; + return LA_FLG_BINDTO | LA_FLG_BINDFROM; +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + fprintf (stderr, "%s\n", __func__); + if (*cookie != TST_COOKIE_VAL) + { + struct link_map *map = (void *) *cookie; + fprintf (stderr, "%s\n", map->l_name); + } + assert (*cookie == TST_COOKIE_VAL); + return 0; +} + +void +la_preinit (uintptr_t *cookie) +{ + fprintf (stderr, "%s\n", __func__); + assert (*cookie == TST_COOKIE_VAL); +} + +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__); + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return sym->st_value; +} + +#ifdef __i386__ +Elf32_Addr +la_i86_gnu_pltenter (Elf32_Sym *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_i86_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return sym->st_value; +} +#elif defined __x86_64__ +Elf64_Addr +la_x86_64_gnu_pltenter (Elf64_Sym *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_x86_64_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return sym->st_value; +} +#elif defined __sparc__ && !defined __arch64__ +Elf32_Addr +la_sparc32_gnu_pltenter (Elf32_Sym *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_sparc32_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return sym->st_value; +} +#elif defined __sparc__ && defined __arch64__ +Elf64_Addr +la_sparc64_gnu_pltenter (Elf64_Sym *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_sparc64_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return sym->st_value; +} +#elif !defined HAVE_ARCH_PLTENTER +# warning "pltenter for architecture not supported" +#endif + +#ifdef __i386__ +unsigned int +la_i86_gnu_pltexit (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const struct La_i86_regs *inregs, + struct La_i86_retval *outregs, const char *symname) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return 0; +} +#elif defined __x86_64__ +unsigned int +la_x86_64_gnu_pltexit (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const struct La_x86_64_regs *inregs, + struct La_x86_64_retval *outregs, const char *symname) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return 0; +} +#elif defined __sparc__ && !defined __arch64__ +unsigned int +la_sparc32_gnu_pltexit (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const struct La_sparc32_regs *inregs, + struct La_sparc32_retval *outregs, const char *symname) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return 0; +} +#elif defined __sparc__ && defined __arch64__ +unsigned int +la_sparc64_gnu_pltexit (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const struct La_sparc64_regs *inregs, + struct La_sparc64_retval *outregs, const char *symname) +{ + /* Should not be here in dynamically loaded auditmod. */ + assert (0); + return 0; +} +#elif !defined HAVE_ARCH_PLTEXIT +# warning "pltexit for architecture not supported" +#endif diff --git a/elf/tst-loadaudit.c b/elf/tst-loadaudit.c new file mode 100644 index 0000000000..4bf86d06a8 --- /dev/null +++ b/elf/tst-loadaudit.c @@ -0,0 +1,138 @@ +/* Check dlload_audit_module. + Copyright (C) 2021-2023 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 * +dlload_audit_module (const char *file, int flags); + +static int +handle_restart (void) +{ + void *ah = dlload_audit_module ("tst-dynauditmod.so", 0); + + TEST_VERIFY (ah != NULL); + + { + 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; + + struct support_capture_subprocess result + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-loadaudit", 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 }, +#if __WORDSIZE == 32 + { "la_symbind32", false }, +#elif __WORDSIZE == 64 + { "la_symbind64", false }, +#endif +#define STRING(s) __STRING (s) + { "la_" STRING (ARCH_LA_PLTENTER), false }, + { "la_" STRING (ARCH_LA_PLTEXIT), false }, + }; + + /* 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); + + /* Check that symbols are resolved, except for the last 3. + symbind, pltenter, pltexit are not allowed for dynamically loaded mod. */ + for (int i = 0; i < array_length (audit_iface); i++) + TEST_COMPARE (audit_iface[i].found, i < array_length (audit_iface) - 3); + + support_capture_subprocess_free (&result); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/include/link.h b/include/link.h index 1d74feb2bd..31f34540fc 100644 --- a/include/link.h +++ b/include/link.h @@ -347,6 +347,7 @@ struct link_map size_t l_relro_size; unsigned long long int l_serial; + unsigned int l_naudit; }; #include diff --git a/manual/dynlink.texi b/manual/dynlink.texi index 6a4a50d3f0..898354ebe9 100644 --- a/manual/dynlink.texi +++ b/manual/dynlink.texi @@ -209,6 +209,7 @@ This function is a GNU extension. @c dladdr1 @c dlclose @c dlerror +@c dlload_audit_module @c dlmopen @c dlopen @c dlsym diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index c99dad77cc..1a377061f8 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -399,6 +399,10 @@ struct rtld_global /* Used to store the audit information for the link map of the dynamic loader. */ struct auditstate _dl_rtld_auditstate[DL_NNS]; + + /* List of auditing interfaces. */ + struct audit_ifaces *_dl_audit; + unsigned int _dl_naudit; #endif #if !PTHREAD_IN_LIBC && defined SHARED \ @@ -689,12 +693,11 @@ struct rtld_global_ro dlopen. */ int (*_dl_find_object) (void *, struct dl_find_object *); + /* Loads audit module. */ + void *(*_dlload_audit_module) (const char *name, int flags); + /* Dynamic linker operations used after static dlopen. */ const struct dlfcn_hook *_dl_dlfcn_hook; - - /* List of auditing interfaces. */ - struct audit_ifaces *_dl_audit; - unsigned int _dl_naudit; }; # define __rtld_global_attribute__ # if IS_IN (rtld) diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 4e3200ef55..b3bff7135b 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2294,6 +2294,7 @@ GLIBC_2.36 arc4random_buf F GLIBC_2.36 arc4random_uniform F GLIBC_2.36 c8rtomb F GLIBC_2.36 mbrtoc8 F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index b66fadef40..e0defa9e33 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2633,3 +2633,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index f918bb2d48..fd72907a44 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2730,6 +2730,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 093043a533..b1cd1087bc 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2394,3 +2394,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index f28402fe03..0d124f6f73 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -514,6 +514,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index e2f56880ed..b095d01781 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -511,6 +511,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 319d92356e..25eede829b 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2670,3 +2670,4 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 6450e17ebe..ea3d616424 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2619,6 +2619,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 0a24ec9afd..a1b6f99e0a 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2803,6 +2803,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 02c65b6482..b8819f22c1 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2568,6 +2568,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 62faaf4c00..bff3a565ed 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2154,3 +2154,4 @@ GLIBC_2.36 wprintf F GLIBC_2.36 write F GLIBC_2.36 writev F GLIBC_2.36 wscanf F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 16243a7a92..32e766d86e 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -515,6 +515,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 564a553b27..322604f951 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2746,6 +2746,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index e850f47b21..5d2745db86 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2719,3 +2719,4 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 37178c503f..9607647f7c 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2716,3 +2716,4 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 3b30b31466..010e0fdb57 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2711,6 +2711,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 0e358570a2..cf178341e9 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2709,6 +2709,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 59c598b98f..2740c1b776 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2717,6 +2717,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 2f7f1ccaf7..92cf1ff6ba 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2619,6 +2619,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 463e01ab84..b712d54d47 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2758,3 +2758,4 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index ffdb8819d5..38cea3234a 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2140,3 +2140,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 405d40d11c..806a3585ef 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2773,6 +2773,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index ce89602b93..ea51bbafca 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2806,6 +2806,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 849863e639..abbb22d958 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2527,6 +2527,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index b2ccee08c6..3f39ec1ea3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2829,3 +2829,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index ff90d1bff2..42fd36421a 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2396,3 +2396,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index f1017f6ec5..82e85c44c2 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2596,3 +2596,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 5ca051a9eb..4ea4a4202b 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2771,6 +2771,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 0e0b3df973..07bd8e0c36 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2564,6 +2564,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 5b48168ec6..3bb628ccab 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2626,6 +2626,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index c42b39cea8..51efda8b4f 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2623,6 +2623,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 5a0a662dee..e6e6a4f335 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2766,6 +2766,7 @@ GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F GLIBC_2.37 __ppoll64_chk F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 9ec4a0bc7f..f8bdf8b036 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2591,6 +2591,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 367c8d0a03..2dda5a2d7d 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2542,6 +2542,7 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 6a614efb62..23c1f31348 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2648,3 +2648,4 @@ GLIBC_2.36 pidfd_open F GLIBC_2.36 pidfd_send_signal F GLIBC_2.36 process_madvise F GLIBC_2.36 process_mrelease F +GLIBC_2.38 dlload_audit_module F