From 542058db63366b506a72e31e2c92d6ecd02569ae Mon Sep 17 00:00:00 2001 From: xujing Date: Mon, 1 Aug 2022 11:16:49 +0800 Subject: [PATCH] sync patches from upstream community --- ...e-_dl_skip_args_internal-declaration.patch | 34 ++ ...so-_start-to-separate-file-and-drop-.patch | 188 ++++++++ ...-rtld_active-to-determine-ld.so-stat.patch | 400 ++++++++++++++++++ ...BUG-warning-in-_dl_start_args_adjust.patch | 30 ++ glibc.spec | 12 +- linux-Add-a-getauxval-test-BZ-23293.patch | 114 +++++ ...RGV_NOT_RELRO-and-make-_dl_skip_args.patch | 299 +++++++++++++ ...ic-argv-adjustment-in-ld.so-BZ-23293.patch | 305 +++++++++++++ 8 files changed, 1381 insertions(+), 1 deletion(-) create mode 100644 Remove-_dl_skip_args_internal-declaration.patch create mode 100644 aarch64-Move-ld.so-_start-to-separate-file-and-drop-.patch create mode 100644 dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch create mode 100644 elf-Fix-DNDEBUG-warning-in-_dl_start_args_adjust.patch create mode 100644 linux-Add-a-getauxval-test-BZ-23293.patch create mode 100644 rtld-Remove-DL_ARGV_NOT_RELRO-and-make-_dl_skip_args.patch create mode 100644 rtld-Use-generic-argv-adjustment-in-ld.so-BZ-23293.patch diff --git a/Remove-_dl_skip_args_internal-declaration.patch b/Remove-_dl_skip_args_internal-declaration.patch new file mode 100644 index 0000000..1970f11 --- /dev/null +++ b/Remove-_dl_skip_args_internal-declaration.patch @@ -0,0 +1,34 @@ +From 707efc2955a90299d8af8211756e2256fbc20c6e Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +Date: Wed, 6 Apr 2022 16:56:07 +0100 +Subject: [PATCH] Remove _dl_skip_args_internal declaration + +Conflict:NA +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=707efc2955a90299d8af8211756e2256fbc20c6e + +It does not seem to be used. + +Reviewed-by: Florian Weimer +--- + sysdeps/generic/ldsodefs.h | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 44750461a9..29f005499b 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -781,11 +781,6 @@ extern char **_dl_argv + rtld_hidden_proto (_dl_argv) + #if IS_IN (rtld) + extern unsigned int _dl_skip_args attribute_hidden +-# ifndef DL_ARGV_NOT_RELRO +- attribute_relro +-# endif +- ; +-extern unsigned int _dl_skip_args_internal attribute_hidden + # ifndef DL_ARGV_NOT_RELRO + attribute_relro + # endif +-- +2.27.0 + diff --git a/aarch64-Move-ld.so-_start-to-separate-file-and-drop-.patch b/aarch64-Move-ld.so-_start-to-separate-file-and-drop-.patch new file mode 100644 index 0000000..15738b9 --- /dev/null +++ b/aarch64-Move-ld.so-_start-to-separate-file-and-drop-.patch @@ -0,0 +1,188 @@ +From 1da064c015dce624cb19fcdc0bace7af2bd8caec Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +Date: Thu, 30 Dec 2021 17:08:36 +0000 +Subject: [PATCH 4/4] aarch64: Move ld.so _start to separate file and drop + _dl_skip_args + +Conflict:NA +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=1da064c015dce624cb19fcdc0bace7af2bd8caec + +A separate asm file is easier to maintain than a macro that expands to +inline asm. + +The RTLD_START macro is only needed now because _dl_start is local in +rtld.c, but _start has to call it, if _dl_start was made hidden then it +could be empty. + +_dl_skip_args is no longer needed. + +Reviewed-by: Adhemerval Zanella +--- + sysdeps/aarch64/Makefile | 1 + + sysdeps/aarch64/dl-machine.h | 77 +----------------------------------- + sysdeps/aarch64/dl-start.S | 53 +++++++++++++++++++++++++ + 3 files changed, 56 insertions(+), 75 deletions(-) + create mode 100644 sysdeps/aarch64/dl-start.S + +diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile +index 7183895d04..17fb1c5b72 100644 +--- a/sysdeps/aarch64/Makefile ++++ b/sysdeps/aarch64/Makefile +@@ -33,6 +33,7 @@ tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so + endif + + ifeq ($(subdir),elf) ++sysdep-rtld-routines += dl-start + sysdep-dl-routines += tlsdesc dl-tlsdesc + gen-as-const-headers += dl-link.sym + +diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h +index b40050a981..fe120bb507 100644 +--- a/sysdeps/aarch64/dl-machine.h ++++ b/sysdeps/aarch64/dl-machine.h +@@ -105,81 +105,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + return lazy; + } + +-/* Initial entry point for the dynamic linker. The C function +- _dl_start is the real entry point, its return value is the user +- program's entry point */ +-#ifdef __LP64__ +-# define RTLD_START RTLD_START_1 ("x", "3", "sp") +-#else +-# define RTLD_START RTLD_START_1 ("w", "2", "wsp") +-#endif +- +- +-#define RTLD_START_1(PTR, PTR_SIZE_LOG, PTR_SP) asm ("\ +-.text \n\ +-.globl _start \n\ +-.type _start, %function \n\ +-.globl _dl_start_user \n\ +-.type _dl_start_user, %function \n\ +-_start: \n\ +- // bti c \n\ +- hint 34 \n\ +- mov " PTR "0, " PTR_SP " \n\ +- bl _dl_start \n\ +- // returns user entry point in x0 \n\ +- mov x21, x0 \n\ +-_dl_start_user: \n\ +- // get the original arg count \n\ +- ldr " PTR "1, [sp] \n\ +- // get the argv address \n\ +- add " PTR "2, " PTR_SP ", #(1<<" PTR_SIZE_LOG ") \n\ +- // get _dl_skip_args to see if we were \n\ +- // invoked as an executable \n\ +- adrp x4, _dl_skip_args \n\ +- ldr w4, [x4, #:lo12:_dl_skip_args] \n\ +- // do we need to adjust argc/argv \n\ +- cmp w4, 0 \n\ +- beq .L_done_stack_adjust \n\ +- // subtract _dl_skip_args from original arg count \n\ +- sub " PTR "1, " PTR "1, " PTR "4 \n\ +- // store adjusted argc back to stack \n\ +- str " PTR "1, [sp] \n\ +- // find the first unskipped argument \n\ +- mov " PTR "3, " PTR "2 \n\ +- add " PTR "4, " PTR "2, " PTR "4, lsl #" PTR_SIZE_LOG " \n\ +- // shuffle argv down \n\ +-1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\ +- str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\ +- cmp " PTR "5, #0 \n\ +- bne 1b \n\ +- // shuffle envp down \n\ +-1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\ +- str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\ +- cmp " PTR "5, #0 \n\ +- bne 1b \n\ +- // shuffle auxv down \n\ +-1: ldp " PTR "0, " PTR "5, [x4, #(2<<" PTR_SIZE_LOG ")]! \n\ +- stp " PTR "0, " PTR "5, [x3], #(2<<" PTR_SIZE_LOG ") \n\ +- cmp " PTR "0, #0 \n\ +- bne 1b \n\ +- // Update _dl_argv \n\ +- adrp x3, __GI__dl_argv \n\ +- str " PTR "2, [x3, #:lo12:__GI__dl_argv] \n\ +-.L_done_stack_adjust: \n\ +- // compute envp \n\ +- add " PTR "3, " PTR "2, " PTR "1, lsl #" PTR_SIZE_LOG " \n\ +- add " PTR "3, " PTR "3, #(1<<" PTR_SIZE_LOG ") \n\ +- adrp x16, _rtld_local \n\ +- add " PTR "16, " PTR "16, #:lo12:_rtld_local \n\ +- ldr " PTR "0, [x16] \n\ +- bl _dl_init \n\ +- // load the finalizer function \n\ +- adrp x0, _dl_fini \n\ +- add " PTR "0, " PTR "0, #:lo12:_dl_fini \n\ +- // jump to the user_s entry point \n\ +- mov x16, x21 \n\ +- br x16 \n\ +-"); ++/* In elf/rtld.c _dl_start should be global so dl-start.S can reference it. */ ++#define RTLD_START asm (".globl _dl_start"); + + #define elf_machine_type_class(type) \ + ((((type) == AARCH64_R(JUMP_SLOT) \ +diff --git a/sysdeps/aarch64/dl-start.S b/sysdeps/aarch64/dl-start.S +new file mode 100644 +index 0000000000..a3a57bd5a1 +--- /dev/null ++++ b/sysdeps/aarch64/dl-start.S +@@ -0,0 +1,53 @@ ++/* ld.so _start code. ++ Copyright (C) 2022 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 ++ ++ENTRY (_start) ++ /* Create an initial frame with 0 LR and FP */ ++ cfi_undefined (x30) ++ mov x29, #0 ++ mov x30, #0 ++ ++ mov x0, sp ++ PTR_ARG (0) ++ bl _dl_start ++ /* Returns user entry point in x0. */ ++ mov PTR_REG (21), PTR_REG (0) ++.globl _dl_start_user ++.type _dl_start_user, %function ++_dl_start_user: ++ /* Get argc. */ ++ ldr PTR_REG (1), [sp] ++ /* Get argv. */ ++ add x2, sp, PTR_SIZE ++ /* Compute envp. */ ++ add PTR_REG (3), PTR_REG (2), PTR_REG (1), lsl PTR_LOG_SIZE ++ add PTR_REG (3), PTR_REG (3), PTR_SIZE ++ adrp x16, _rtld_local ++ add PTR_REG (16), PTR_REG (16), :lo12:_rtld_local ++ ldr PTR_REG (0), [x16] ++ bl _dl_init ++ /* Load the finalizer function. */ ++ adrp x0, _dl_fini ++ add PTR_REG (0), PTR_REG (0), :lo12:_dl_fini ++ /* Jump to the user's entry point. */ ++ mov x16, x21 ++ br x16 ++END (_start) +-- +2.27.0 + diff --git a/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch b/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch new file mode 100644 index 0000000..2a4e89b --- /dev/null +++ b/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch @@ -0,0 +1,400 @@ +From 8dcb6d0af07fda3607b541857e4f3970a74ed55b Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Tue, 26 Apr 2022 14:23:02 +0200 +Subject: [PATCH] dlfcn: Do not use rtld_active () to determine ld.so state + (bug 29078) + +Conflict:adapt Makefile context +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=8dcb6d0af07fda3607b541857e4f3970a74ed55b + +When audit modules are loaded, ld.so initialization is not yet +complete, and rtld_active () returns false even though ld.so is +mostly working. Instead, the static dlopen hook is used, but that +does not work at all because this is not a static dlopen situation. + +Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework +static dlopen hooks") moved the hook pointer into _rtld_global_ro, +which means that separate protection is not needed anymore and the +hook pointer can be checked directly. + +The guard for disabling libio vtable hardening in _IO_vtable_check +should stay for now. + +Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so: +Examine GLRO to detect inactive loader [BZ #20204]"). + +Reviewed-by: Adhemerval Zanella +--- + dlfcn/dladdr.c | 2 +- + dlfcn/dladdr1.c | 2 +- + dlfcn/dlclose.c | 2 +- + dlfcn/dlerror.c | 2 +- + dlfcn/dlinfo.c | 2 +- + dlfcn/dlmopen.c | 2 +- + dlfcn/dlopen.c | 2 +- + dlfcn/dlopenold.c | 2 +- + dlfcn/dlsym.c | 2 +- + dlfcn/dlvsym.c | 2 +- + elf/Makefile | 6 +++ + elf/dl-libc.c | 8 ++-- + elf/tst-audit26.c | 35 +++++++++++++++ + elf/tst-auditmod26.c | 104 +++++++++++++++++++++++++++++++++++++++++++ + 14 files changed, 159 insertions(+), 14 deletions(-) + create mode 100644 elf/tst-audit26.c + create mode 100644 elf/tst-auditmod26.c + +diff --git a/dlfcn/dladdr.c b/dlfcn/dladdr.c +index ead117326f..d188d0e289 100644 +--- a/dlfcn/dladdr.c ++++ b/dlfcn/dladdr.c +@@ -24,7 +24,7 @@ int + __dladdr (const void *address, Dl_info *info) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dladdr (address, info); + #endif + return _dl_addr (address, info, NULL, NULL); +diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c +index 5dadfd1220..e0c9526c90 100644 +--- a/dlfcn/dladdr1.c ++++ b/dlfcn/dladdr1.c +@@ -24,7 +24,7 @@ int + __dladdr1 (const void *address, Dl_info *info, void **extra, int flags) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dladdr1 (address, info, extra, flags); + #endif + +diff --git a/dlfcn/dlclose.c b/dlfcn/dlclose.c +index a9921c3169..aab88c47fc 100644 +--- a/dlfcn/dlclose.c ++++ b/dlfcn/dlclose.c +@@ -24,7 +24,7 @@ int + __dlclose (void *handle) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlclose (handle); + #endif + +diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c +index 3bf6049e3c..b899d252a1 100644 +--- a/dlfcn/dlerror.c ++++ b/dlfcn/dlerror.c +@@ -32,7 +32,7 @@ char * + __dlerror (void) + { + # ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlerror (); + # endif + +diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c +index fc63c02681..068db5260c 100644 +--- a/dlfcn/dlinfo.c ++++ b/dlfcn/dlinfo.c +@@ -89,7 +89,7 @@ dlinfo_implementation (void *handle, int request, void *arg) + int + ___dlinfo (void *handle, int request, void *arg) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg); + else + return dlinfo_implementation (handle, request, arg); +diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c +index 2437f5ce22..b41778f16c 100644 +--- a/dlfcn/dlmopen.c ++++ b/dlfcn/dlmopen.c +@@ -80,7 +80,7 @@ dlmopen_implementation (Lmid_t nsid, const char *file, int mode, + void * + ___dlmopen (Lmid_t nsid, const char *file, int mode) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlmopen (nsid, file, mode, RETURN_ADDRESS (0)); + else + return dlmopen_implementation (nsid, file, mode, RETURN_ADDRESS (0)); +diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c +index 846ca38338..2696dde4b1 100644 +--- a/dlfcn/dlopen.c ++++ b/dlfcn/dlopen.c +@@ -75,7 +75,7 @@ dlopen_implementation (const char *file, int mode, void *dl_caller) + void * + ___dlopen (const char *file, int mode) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0)); + else + return dlopen_implementation (file, mode, RETURN_ADDRESS (0)); +diff --git a/dlfcn/dlopenold.c b/dlfcn/dlopenold.c +index 67601434df..5c21a00496 100644 +--- a/dlfcn/dlopenold.c ++++ b/dlfcn/dlopenold.c +@@ -70,7 +70,7 @@ __dlopen_nocheck (const char *file, int mode) + mode |= RTLD_LAZY; + args.mode = mode; + +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0)); + + return _dlerror_run (dlopen_doit, &args) ? NULL : args.new; +diff --git a/dlfcn/dlsym.c b/dlfcn/dlsym.c +index a71f8ae247..2e9ff98e79 100644 +--- a/dlfcn/dlsym.c ++++ b/dlfcn/dlsym.c +@@ -62,7 +62,7 @@ dlsym_implementation (void *handle, const char *name, void *dl_caller) + void * + ___dlsym (void *handle, const char *name) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlsym (handle, name, RETURN_ADDRESS (0)); + else + return dlsym_implementation (handle, name, RETURN_ADDRESS (0)); +diff --git a/dlfcn/dlvsym.c b/dlfcn/dlvsym.c +index 72219d6da6..caa46ba1e0 100644 +--- a/dlfcn/dlvsym.c ++++ b/dlfcn/dlvsym.c +@@ -65,7 +65,7 @@ dlvsym_implementation (void *handle, const char *name, const char *version, + void * + ___dlvsym (void *handle, const char *name, const char *version) + { +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlvsym (handle, name, version, + RETURN_ADDRESS (0)); + else +diff --git a/elf/Makefile b/elf/Makefile +index 8ed6c3b0b1..e4907d5de9 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -390,6 +390,7 @@ tests += \ + tst-audit16 \ + tst-audit17 \ + tst-audit21 \ ++ tst-audit26 \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -767,6 +768,7 @@ modules-names = \ + tst-auditmod12 \ + tst-auditmod21a \ + tst-auditmod21b \ ++ tst-auditmod26 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -2286,6 +2288,10 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ + $(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so + tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so + ++$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so ++$(objpfx)tst-auditmod26.so: $(libsupport) ++tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.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-libc.c b/elf/dl-libc.c +index a7180d0af8..266e068da6 100644 +--- a/elf/dl-libc.c ++++ b/elf/dl-libc.c +@@ -156,7 +156,7 @@ __libc_dlopen_mode (const char *name, int mode) + args.caller_dlopen = RETURN_ADDRESS (0); + + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlopen_mode (name, mode); + #endif + return dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map; +@@ -184,7 +184,7 @@ __libc_dlsym (void *map, const char *name) + args.name = name; + + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlsym (map, name); + #endif + return (dlerror_run (do_dlsym, &args) ? NULL +@@ -198,7 +198,7 @@ void * + __libc_dlvsym (void *map, const char *name, const char *version) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlvsym (map, name, version); + #endif + +@@ -221,7 +221,7 @@ int + __libc_dlclose (void *map) + { + #ifdef SHARED +- if (!rtld_active ()) ++ if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->libc_dlclose (map); + #endif + return dlerror_run (do_dlclose, map); +diff --git a/elf/tst-audit26.c b/elf/tst-audit26.c +new file mode 100644 +index 0000000000..3f920e83ba +--- /dev/null ++++ b/elf/tst-audit26.c +@@ -0,0 +1,35 @@ ++/* Check the usability of functions in audit modules. ++ Copyright (C) 2022 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 int ++do_test (void) ++{ ++ /* Check that the audit module has been loaded. */ ++ void *handle = xdlopen ("mapped to libc", RTLD_LOCAL | RTLD_NOW); ++ TEST_VERIFY (handle ++ == xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD)); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod26.c +new file mode 100644 +index 0000000000..db7ba95abe +--- /dev/null ++++ b/elf/tst-auditmod26.c +@@ -0,0 +1,104 @@ ++/* Check the usability of functions in audit modules. Audit module. ++ Copyright (C) 2022 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 ++ ++unsigned int ++la_version (unsigned int current) ++{ ++ /* Exercise various functions. */ ++ ++ /* Check dlopen, dlsym, dlclose. */ ++ void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW); ++ void *ptr = xdlsym (handle, "sincos"); ++ TEST_VERIFY (ptr != NULL); ++ ptr = dlsym (handle, "SINCOS"); ++ TEST_VERIFY (ptr == NULL); ++ const char *message = dlerror (); ++ TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL); ++ ptr = dlsym (handle, "SINCOS"); ++ TEST_VERIFY (ptr == NULL); ++ xdlclose (handle); ++ TEST_COMPARE_STRING (dlerror (), NULL); ++ ++ handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD); ++ ++ /* Check dlvsym. _exit is unlikely to gain another symbol ++ version. */ ++ TEST_VERIFY (xdlsym (handle, "_exit") ++ == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING)); ++ ++ /* Check dlinfo. */ ++ { ++ void *handle2 = NULL; ++ TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0); ++ TEST_VERIFY (handle2 == handle); ++ } ++ ++ /* Check dladdr and dladdr1. */ ++ Dl_info info = { }; ++ TEST_VERIFY (dladdr (&_exit, &info) != 0); ++ if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */ ++ TEST_COMPARE_STRING (info.dli_sname, "_exit"); ++ TEST_VERIFY (info.dli_saddr == &_exit); ++ TEST_VERIFY (strstr (info.dli_fname, LIBC_SO)); ++ void *extra_info; ++ memset (&info, 0, sizeof (info)); ++ TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0); ++ TEST_VERIFY (extra_info == handle); ++ ++ /* Verify that dlmopen creates a new namespace. */ ++ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ TEST_VERIFY (dlmopen_handle != handle); ++ memset (&info, 0, sizeof (info)); ++ extra_info = NULL; ++ ptr = xdlsym (dlmopen_handle, "_exit"); ++ TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0); ++ TEST_VERIFY (extra_info == dlmopen_handle); ++ xdlclose (dlmopen_handle); ++ ++ /* Terminate the process with an error state. This does not happen ++ automatically because the audit module state is not shared with ++ the main program. */ ++ if (support_record_failure_is_failed ()) ++ { ++ fflush (stdout); ++ fflush (stderr); ++ _exit (1); ++ } ++ ++ return LAV_CURRENT; ++} ++ ++char * ++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) ++{ ++ if (strcmp (name, "mapped to libc") == 0) ++ return (char *) LIBC_SO; ++ else ++ return (char *) name; ++} +-- +2.27.0 + diff --git a/elf-Fix-DNDEBUG-warning-in-_dl_start_args_adjust.patch b/elf-Fix-DNDEBUG-warning-in-_dl_start_args_adjust.patch new file mode 100644 index 0000000..4b36ff5 --- /dev/null +++ b/elf-Fix-DNDEBUG-warning-in-_dl_start_args_adjust.patch @@ -0,0 +1,30 @@ +From c1ada668a381e122ee37cb8be7f0637111f63ea7 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Tue, 28 Jun 2022 10:40:16 +0200 +Subject: [PATCH] elf: Fix -DNDEBUG warning in _dl_start_args_adjust + +Conflict:NA +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=c1ada668a381e122ee37cb8be7f0637111f63ea7 + +This is another blocker for building glibc with the default +-Werror setting and -DNDEBUG. +--- + elf/rtld.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/elf/rtld.c b/elf/rtld.c +index f5a3d1968f..cbbaf4a331 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1307,7 +1307,7 @@ _dl_start_args_adjust (int skip_args) + return; + + /* Sanity check. */ +- intptr_t argc = (intptr_t) sp[0] - skip_args; ++ intptr_t argc __attribute__ ((unused)) = (intptr_t) sp[0] - skip_args; + assert (argc == _dl_argc); + + /* Adjust argc on stack. */ +-- +2.27.0 + diff --git a/glibc.spec b/glibc.spec index b7c613c..ee6f769 100644 --- a/glibc.spec +++ b/glibc.spec @@ -66,7 +66,7 @@ ############################################################################## Name: glibc Version: 2.34 -Release: 92 +Release: 93 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -226,6 +226,13 @@ Patch138: Linux-Avoid-closing-1-on-failure-in-__closefrom_fall.patch Patch139: Fix-deadlock-when-pthread_atfork-handler-calls-pthre.patch Patch140: linux-Fix-mq_timereceive-check-for-32-bit-fallback-c.patch Patch141: elf-Fix-compile-error-with-Werror-and-DNDEBUG.patch +Patch142: dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch +Patch143: Remove-_dl_skip_args_internal-declaration.patch +Patch144: rtld-Use-generic-argv-adjustment-in-ld.so-BZ-23293.patch +Patch145: rtld-Remove-DL_ARGV_NOT_RELRO-and-make-_dl_skip_args.patch +Patch146: linux-Add-a-getauxval-test-BZ-23293.patch +Patch147: aarch64-Move-ld.so-_start-to-separate-file-and-drop-.patch +Patch148: elf-Fix-DNDEBUG-warning-in-_dl_start_args_adjust.patch Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch @@ -1407,6 +1414,9 @@ fi %endif %changelog +* Mon Aug 1 2022 xujing - 2.34-93 +- sync patches from upstream community + * Thu Jul 28 2022 Qingqing Li - 2.34-92 - optimize Obsoletes version diff --git a/linux-Add-a-getauxval-test-BZ-23293.patch b/linux-Add-a-getauxval-test-BZ-23293.patch new file mode 100644 index 0000000..f3f41cf --- /dev/null +++ b/linux-Add-a-getauxval-test-BZ-23293.patch @@ -0,0 +1,114 @@ +From 9faf5262c77487c96da8a3e961b88c0b1879e186 Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +Date: Tue, 3 May 2022 13:18:04 +0100 +Subject: [PATCH 3/4] linux: Add a getauxval test [BZ #23293] + +Conflict:adapt Makefile context +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=9faf5262c77487c96da8a3e961b88c0b1879e186 + +This is for bug 23293 and it relies on the glibc test system running +tests via explicit ld.so invokation by default. + +Reviewed-by: Florian Weimer +Reviewed-by: Adhemerval Zanella +--- + sysdeps/unix/sysv/linux/Makefile | 1 + + sysdeps/unix/sysv/linux/tst-getauxval.c | 74 +++++++++++++++++++++++++ + 2 files changed, 75 insertions(+) + create mode 100644 sysdeps/unix/sysv/linux/tst-getauxval.c + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index ca953804d0..89cb005c7d 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -126,6 +126,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-close_range \ + tst-prctl \ + tst-scm_rights \ ++ tst-getauxval \ + # tests + + # Test for the symbol version of fcntl that was replaced in glibc 2.28. +diff --git a/sysdeps/unix/sysv/linux/tst-getauxval.c b/sysdeps/unix/sysv/linux/tst-getauxval.c +new file mode 100644 +index 0000000000..c4b6195743 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-getauxval.c +@@ -0,0 +1,74 @@ ++/* Basic test for getauxval. ++ Copyright (C) 2022 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 ++ ++static int missing; ++static int mismatch; ++ ++static void ++check_nonzero (unsigned long t, const char *s) ++{ ++ unsigned long v = getauxval (t); ++ printf ("%s: %lu (0x%lx)\n", s, v, v); ++ if (v == 0) ++ missing++; ++} ++ ++static void ++check_eq (unsigned long t, const char *s, unsigned long want) ++{ ++ unsigned long v = getauxval (t); ++ printf ("%s: %lu want: %lu\n", s, v, want); ++ if (v != want) ++ mismatch++; ++} ++ ++#define NZ(x) check_nonzero (x, #x) ++#define EQ(x, want) check_eq (x, #x, want) ++ ++static int ++do_test (void) ++{ ++ /* These auxv entries should be non-zero on Linux. */ ++ NZ (AT_PHDR); ++ NZ (AT_PHENT); ++ NZ (AT_PHNUM); ++ NZ (AT_PAGESZ); ++ NZ (AT_ENTRY); ++ NZ (AT_CLKTCK); ++ NZ (AT_RANDOM); ++ NZ (AT_EXECFN); ++ if (missing) ++ FAIL_EXIT1 ("Found %d missing auxv entries.\n", missing); ++ ++ /* Check against syscalls. */ ++ EQ (AT_UID, getuid ()); ++ EQ (AT_EUID, geteuid ()); ++ EQ (AT_GID, getgid ()); ++ EQ (AT_EGID, getegid ()); ++ if (mismatch) ++ FAIL_EXIT1 ("Found %d mismatching auxv entries.\n", mismatch); ++ ++ return 0; ++} ++ ++#include +-- +2.27.0 + diff --git a/rtld-Remove-DL_ARGV_NOT_RELRO-and-make-_dl_skip_args.patch b/rtld-Remove-DL_ARGV_NOT_RELRO-and-make-_dl_skip_args.patch new file mode 100644 index 0000000..5b139ba --- /dev/null +++ b/rtld-Remove-DL_ARGV_NOT_RELRO-and-make-_dl_skip_args.patch @@ -0,0 +1,299 @@ +From 86147bbeec25624cb26bb7646cdbc3a49bc56bf5 Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +Date: Tue, 3 May 2021 17:01:44 +0100 +Subject: [PATCH 2/4] rtld: Remove DL_ARGV_NOT_RELRO and make _dl_skip_args + const + +Conflict:adapt 2022 to 2021 +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=86147bbeec25624cb26bb7646cdbc3a49bc56bf5 + +_dl_skip_args is always 0, so the target specific code that modifies +argv after relro protection is applied is no longer used. + +After the patch relro protection is applied to _dl_argv consistently +on all targets. + +Reviewed-by: Florian Weimer +Reviewed-by: Adhemerval Zanella +--- + elf/rtld.c | 10 ++-------- + sysdeps/aarch64/dl-sysdep.h | 4 ---- + sysdeps/alpha/dl-sysdep.h | 23 ----------------------- + sysdeps/arc/dl-sysdep.h | 4 ---- + sysdeps/arm/dl-sysdep.h | 4 ---- + sysdeps/csky/dl-sysdep.h | 23 ----------------------- + sysdeps/generic/ldsodefs.h | 13 +++---------- + sysdeps/ia64/dl-sysdep.h | 23 ----------------------- + sysdeps/nios2/dl-sysdep.h | 4 ---- + sysdeps/s390/s390-32/dl-sysdep.h | 23 ----------------------- + sysdeps/sparc/dl-sysdep.h | 23 ----------------------- + sysdeps/unix/sysv/linux/ia64/dl-sysdep.h | 4 ---- + 12 files changed, 5 insertions(+), 153 deletions(-) + delete mode 100644 sysdeps/alpha/dl-sysdep.h + delete mode 100644 sysdeps/csky/dl-sysdep.h + delete mode 100644 sysdeps/ia64/dl-sysdep.h + delete mode 100644 sysdeps/s390/s390-32/dl-sysdep.h + delete mode 100644 sysdeps/sparc/dl-sysdep.h + +diff --git a/elf/rtld.c b/elf/rtld.c +index 6e8ed430e2..069940d73f 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -156,16 +156,10 @@ static void dl_main_state_init (struct dl_main_state *state); + extern char **_environ attribute_hidden; + static void process_envvars (struct dl_main_state *state); + +-#ifdef DL_ARGV_NOT_RELRO +-int _dl_argc attribute_hidden; +-char **_dl_argv = NULL; +-/* Nonzero if we were run directly. */ +-unsigned int _dl_skip_args attribute_hidden; +-#else + int _dl_argc attribute_relro attribute_hidden; + char **_dl_argv attribute_relro = NULL; +-unsigned int _dl_skip_args attribute_relro attribute_hidden; +-#endif ++/* Always 0, only kept for not-yet-updated target start code. */ ++const unsigned int _dl_skip_args attribute_hidden; + rtld_hidden_data_def (_dl_argv) + + #ifndef THREAD_SET_STACK_GUARD +diff --git a/sysdeps/aarch64/dl-sysdep.h b/sysdeps/aarch64/dl-sysdep.h +index 667786671c..1516dd7d3f 100644 +--- a/sysdeps/aarch64/dl-sysdep.h ++++ b/sysdeps/aarch64/dl-sysdep.h +@@ -18,8 +18,4 @@ + + #include_next + +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +- + #define DL_EXTERN_PROTECTED_DATA +diff --git a/sysdeps/alpha/dl-sysdep.h b/sysdeps/alpha/dl-sysdep.h +deleted file mode 100644 +index 3099ee419f..0000000000 +--- a/sysdeps/alpha/dl-sysdep.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-/* System-specific settings for dynamic linker code. Alpha version. +- Copyright (C) 2002-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_next +- +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +diff --git a/sysdeps/arc/dl-sysdep.h b/sysdeps/arc/dl-sysdep.h +index da060ceeee..cf4d160a73 100644 +--- a/sysdeps/arc/dl-sysdep.h ++++ b/sysdeps/arc/dl-sysdep.h +@@ -18,8 +18,4 @@ + + #include_next + +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +- + #define DL_EXTERN_PROTECTED_DATA +diff --git a/sysdeps/arm/dl-sysdep.h b/sysdeps/arm/dl-sysdep.h +index ce7a84a7de..7a99107436 100644 +--- a/sysdeps/arm/dl-sysdep.h ++++ b/sysdeps/arm/dl-sysdep.h +@@ -18,8 +18,4 @@ + + #include_next + +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +- + #define DL_EXTERN_PROTECTED_DATA +diff --git a/sysdeps/csky/dl-sysdep.h b/sysdeps/csky/dl-sysdep.h +deleted file mode 100644 +index fc8a58b94c..0000000000 +--- a/sysdeps/csky/dl-sysdep.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-/* System-specific settings for dynamic linker code. C-SKY version. +- Copyright (C) 2018-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_next +- +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index b69ea2caeb..6716e1f382 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -753,18 +753,11 @@ rtld_hidden_proto (__libc_stack_end) + + /* Parameters passed to the dynamic linker. */ + extern int _dl_argc attribute_hidden attribute_relro; +-extern char **_dl_argv +-#ifndef DL_ARGV_NOT_RELRO +- attribute_relro +-#endif +- ; ++extern char **_dl_argv attribute_relro; + rtld_hidden_proto (_dl_argv) + #if IS_IN (rtld) +-extern unsigned int _dl_skip_args attribute_hidden +-# ifndef DL_ARGV_NOT_RELRO +- attribute_relro +-# endif +- ; ++/* Always 0, only kept for not-yet-updated target start code. */ ++extern const unsigned int _dl_skip_args attribute_hidden; + #endif + #define rtld_progname _dl_argv[0] + +diff --git a/sysdeps/ia64/dl-sysdep.h b/sysdeps/ia64/dl-sysdep.h +deleted file mode 100644 +index e3a58bec24..0000000000 +--- a/sysdeps/ia64/dl-sysdep.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-/* System-specific settings for dynamic linker code. IA-64 version. +- Copyright (C) 2002-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_next +- +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +diff --git a/sysdeps/nios2/dl-sysdep.h b/sysdeps/nios2/dl-sysdep.h +index 0354650042..257b37c258 100644 +--- a/sysdeps/nios2/dl-sysdep.h ++++ b/sysdeps/nios2/dl-sysdep.h +@@ -18,8 +18,4 @@ + + #include_next + +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +- + #define DL_EXTERN_PROTECTED_DATA +diff --git a/sysdeps/s390/s390-32/dl-sysdep.h b/sysdeps/s390/s390-32/dl-sysdep.h +deleted file mode 100644 +index 699b50f156..0000000000 +--- a/sysdeps/s390/s390-32/dl-sysdep.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-/* System-specific settings for dynamic linker code. S/390 version. +- Copyright (C) 2014-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_next +- +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +diff --git a/sysdeps/sparc/dl-sysdep.h b/sysdeps/sparc/dl-sysdep.h +deleted file mode 100644 +index f32f16a107..0000000000 +--- a/sysdeps/sparc/dl-sysdep.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-/* System-specific settings for dynamic linker code. SPARC version. +- Copyright (C) 2002-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_next +- +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +diff --git a/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h +index 0d2a1d093a..aa1de6b361 100644 +--- a/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h ++++ b/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h +@@ -48,8 +48,4 @@ extern int _dl_sysinfo_break attribute_hidden; + ".previous"); + #endif + +-/* _dl_argv cannot be attribute_relro, because _dl_start_user +- might write into it after _dl_start returns. */ +-#define DL_ARGV_NOT_RELRO 1 +- + #endif /* dl-sysdep.h */ +-- +2.27.0 + diff --git a/rtld-Use-generic-argv-adjustment-in-ld.so-BZ-23293.patch b/rtld-Use-generic-argv-adjustment-in-ld.so-BZ-23293.patch new file mode 100644 index 0000000..ced5c29 --- /dev/null +++ b/rtld-Use-generic-argv-adjustment-in-ld.so-BZ-23293.patch @@ -0,0 +1,305 @@ +From ad43cac44a6860eaefcadadfb2acb349921e96bf Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +Date: Fri, 15 Jun 2018 16:14:58 +0100 +Subject: [PATCH 1/4] rtld: Use generic argv adjustment in ld.so [BZ #23293] + +Conflict:adapt rtld.c:1031 context +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=ad43cac44a6860eaefcadadfb2acb349921e96bf + +When an executable is invoked as + + ./ld.so [ld.so-args] ./exe [exe-args] + +then the argv is adujusted in ld.so before calling the entry point of +the executable so ld.so args are not visible to it. On most targets +this requires moving argv, env and auxv on the stack to ensure correct +stack alignment at the entry point. This had several issues: + +- The code for this adjustment on the stack is written in asm as part + of the target specific ld.so _start code which is hard to maintain. + +- The adjustment is done after _dl_start returns, where it's too late + to update GLRO(dl_auxv), as it is already readonly, so it points to + memory that was clobbered by the adjustment. This is bug 23293. + +- _environ is also wrong in ld.so after the adjustment, but it is + likely not used after _dl_start returns so this is not user visible. + +- _dl_argv was updated, but for this it was moved out of relro, which + changes security properties across targets unnecessarily. + +This patch introduces a generic _dl_start_args_adjust function that +handles the argument adjustments after ld.so processed its own args +and before relro protection is applied. + +The same algorithm is used on all targets, _dl_skip_args is now 0, so +existing target specific adjustment code is no longer used. The bug +affects aarch64, alpha, arc, arm, csky, ia64, nios2, s390-32 and sparc, +other targets don't need the change in principle, only for consistency. + +The GNU Hurd start code relied on _dl_skip_args after dl_main returned, +now it checks directly if args were adjusted and fixes the Hurd startup +data accordingly. + +Follow up patches can remove _dl_skip_args and DL_ARGV_NOT_RELRO. + +Tested on aarch64-linux-gnu and cross tested on i686-gnu. + +Reviewed-by: Adhemerval Zanella +--- + elf/rtld.c | 73 ++++++++++++++++++++++++++++------- + sysdeps/mach/hurd/dl-sysdep.c | 30 +++++++------- + 2 files changed, 73 insertions(+), 30 deletions(-) + +diff --git a/elf/rtld.c b/elf/rtld.c +index 578fc14cdb..6e8ed430e2 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1301,6 +1301,62 @@ rtld_setup_main_map (struct link_map *main_map) + } + } + ++/* Adjusts the contents of the stack and related globals for the user ++ entry point. The ld.so processed skip_args arguments and bumped ++ _dl_argv and _dl_argc accordingly. Those arguments are removed from ++ argv here. */ ++static void ++_dl_start_args_adjust (int skip_args) ++{ ++ void **sp = (void **) (_dl_argv - skip_args - 1); ++ void **p = sp + skip_args; ++ ++ if (skip_args == 0) ++ return; ++ ++ /* Sanity check. */ ++ intptr_t argc = (intptr_t) sp[0] - skip_args; ++ assert (argc == _dl_argc); ++ ++ /* Adjust argc on stack. */ ++ sp[0] = (void *) (intptr_t) _dl_argc; ++ ++ /* Update globals in rtld. */ ++ _dl_argv -= skip_args; ++ _environ -= skip_args; ++ ++ /* Shuffle argv down. */ ++ do ++ *++sp = *++p; ++ while (*p != NULL); ++ ++ assert (_environ == (char **) (sp + 1)); ++ ++ /* Shuffle envp down. */ ++ do ++ *++sp = *++p; ++ while (*p != NULL); ++ ++#ifdef HAVE_AUX_VECTOR ++ void **auxv = (void **) GLRO(dl_auxv) - skip_args; ++ GLRO(dl_auxv) = (ElfW(auxv_t) *) auxv; /* Aliasing violation. */ ++ assert (auxv == sp + 1); ++ ++ /* Shuffle auxv down. */ ++ ElfW(auxv_t) ax; ++ char *oldp = (char *) (p + 1); ++ char *newp = (char *) (sp + 1); ++ do ++ { ++ memcpy (&ax, oldp, sizeof (ax)); ++ memcpy (newp, &ax, sizeof (ax)); ++ oldp += sizeof (ax); ++ newp += sizeof (ax); ++ } ++ while (ax.a_type != AT_NULL); ++#endif ++} ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1354,6 +1410,7 @@ dl_main (const ElfW(Phdr) *phdr, + rtld_is_main = true; + + char *argv0 = NULL; ++ char **orig_argv = _dl_argv; + + /* Note the place where the dynamic linker actually came from. */ + GL(dl_rtld_map).l_name = rtld_progname; +@@ -1368,7 +1425,6 @@ dl_main (const ElfW(Phdr) *phdr, + GLRO(dl_lazy) = -1; + } + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1377,14 +1433,12 @@ dl_main (const ElfW(Phdr) *phdr, + if (state.mode != rtld_mode_help) + state.mode = rtld_mode_verify; + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } + else if (! strcmp (_dl_argv[1], "--inhibit-cache")) + { + GLRO(dl_inhibit_cache) = 1; +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1394,7 +1448,6 @@ dl_main (const ElfW(Phdr) *phdr, + state.library_path = _dl_argv[2]; + state.library_path_source = "--library-path"; + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1403,7 +1456,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + GLRO(dl_inhibit_rpath) = _dl_argv[2]; + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1411,14 +1463,12 @@ dl_main (const ElfW(Phdr) *phdr, + { + audit_list_add_string (&state.audit_list, _dl_argv[2]); + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } + else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2) + { + state.preloadarg = _dl_argv[2]; +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1426,7 +1476,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + argv0 = _dl_argv[2]; + +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1434,7 +1483,6 @@ dl_main (const ElfW(Phdr) *phdr, + && _dl_argc > 2) + { + state.glibc_hwcaps_prepend = _dl_argv[2]; +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1442,7 +1490,6 @@ dl_main (const ElfW(Phdr) *phdr, + && _dl_argc > 2) + { + state.glibc_hwcaps_mask = _dl_argv[2]; +- _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; + } +@@ -1451,7 +1498,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + state.mode = rtld_mode_list_tunables; + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1460,7 +1506,6 @@ dl_main (const ElfW(Phdr) *phdr, + { + state.mode = rtld_mode_list_diagnostics; + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + } +@@ -1506,7 +1551,6 @@ dl_main (const ElfW(Phdr) *phdr, + _dl_usage (ld_so_name, NULL); + } + +- ++_dl_skip_args; + --_dl_argc; + ++_dl_argv; + +@@ -1605,6 +1649,9 @@ dl_main (const ElfW(Phdr) *phdr, + /* Set the argv[0] string now that we've processed the executable. */ + if (argv0 != NULL) + _dl_argv[0] = argv0; ++ ++ /* Adjust arguments for the application entry point. */ ++ _dl_start_args_adjust (_dl_argv - orig_argv); + } + else + { +diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c +index 3cbe075615..8373962e62 100644 +--- a/sysdeps/mach/hurd/dl-sysdep.c ++++ b/sysdeps/mach/hurd/dl-sysdep.c +@@ -76,6 +76,7 @@ _dl_sysdep_start (void **start_argptr, + { + void go (intptr_t *argdata) + { ++ char *orig_argv0; + char **p; + + /* Cache the information in various global variables. */ +@@ -84,6 +85,8 @@ _dl_sysdep_start (void **start_argptr, + _environ = &_dl_argv[_dl_argc + 1]; + for (p = _environ; *p++;); /* Skip environ pointers and terminator. */ + ++ orig_argv0 = _dl_argv[0]; ++ + if ((void *) p == _dl_argv[0]) + { + static struct hurd_startup_data nodata; +@@ -173,30 +176,23 @@ _dl_sysdep_start (void **start_argptr, + + /* The call above might screw a few things up. + +- First of all, if _dl_skip_args is nonzero, we are ignoring +- the first few arguments. However, if we have no Hurd startup +- data, it is the magical convention that ARGV[0] == P. The ++ P is the location after the terminating NULL of the list of ++ environment variables. It has to point to the Hurd startup ++ data or if that's missing then P == ARGV[0] must hold. The + startup code in init-first.c will get confused if this is not + the case, so we must rearrange things to make it so. We'll +- overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args]. ++ recompute P and move the Hurd data or the new ARGV[0] there. + +- Secondly, if we need to be secure, it removes some dangerous +- environment variables. If we have no Hurd startup date this +- changes P (since that's the location after the terminating +- NULL in the list of environment variables). We do the same +- thing as in the first case but make sure we recalculate P. +- If we do have Hurd startup data, we have to move the data +- such that it starts just after the terminating NULL in the +- environment list. ++ Note: directly invoked ld.so can move arguments and env vars. + + We use memmove, since the locations might overlap. */ +- if (__libc_enable_secure || _dl_skip_args) +- { +- char **newp; + +- for (newp = _environ; *newp++;); ++ char **newp; ++ for (newp = _environ; *newp++;); + +- if (_dl_argv[-_dl_skip_args] == (char *) p) ++ if (newp != p || _dl_argv[0] != orig_argv0) ++ { ++ if (orig_argv0 == (char *) p) + { + if ((char *) newp != _dl_argv[0]) + { +-- +2.27.0 +