From 210177e07c198c2cde7e5a1125d4b94c26934e8f Mon Sep 17 00:00:00 2001 From: Qingqing Li Date: Wed, 20 Aug 2025 14:39:38 +0800 Subject: [PATCH] sync from glibc upstream, this include 43 patches. 2ce5eb61fc (HEAD -> 238, origin/release/2.38/master) x86-64: Allocate state buffer space for RDI, RSI and RBX 6f076f1366 x86-64: Update _dl_tlsdesc_dynamic to preserve AMX registers 88866d885c x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registers 4b2071eb02 x32/cet: Support shadow stack during startup for Linux 6.10 8572a77d95 x86-64: Remove sysdeps/x86_64/x32/dl-machine.h 89fd3b08ea x86/cet: fix shadow stack test scripts e13036cefa x86-64/cet: Make CET feature check specific to Linux/x86 0ca425964e i386: Remove CET support bits 90ee4db1bf x86-64/cet: Move check-cet.awk to x86_64 1e739f0a04 x86: Move CET infrastructure to x86_64 5d884f8949 x86-64/cet: Move dl-cet.[ch] to x86_64 directories 16c478bc28 i386: Fail if configured with --enable-cet 0412cc8b4f x86-64/cet: Check the restore token in longjmp 9800c19dde i386: Ignore --enable-cet 78b4845046 x86/cet: Add -fcf-protection=none before -fcf-protection=branch e053e7caaf x86/cet: Run some CET tests with shadow stack 0d1abcab55 x86/cet: Don't set CET active by default 027b321811 x86/cet: Check feature_1 in TCB for active IBT and SHSTK 5f6e2a06f6 x86/cet: Enable shadow stack during startup 99fd1f6454 x86/cet: Sync with Linux kernel 6.6 shadow stack interface 9397174e48 x86/cet: Don't disable CET if not single threaded cc47b51930 x86: Modularize sysdeps/x86/dl-cet.c 4c69161b63 x86/cet: Update tst-cet-vfork-1 2c763f814e x86/cet: Check CPU_FEATURE_ACTIVE in permissive mode 1192cdd722 x86/cet: Check legacy shadow stack code in .init_array section db563af070 x86/cet: Add tests for GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK a4003d1500 x86/cet: Check CPU_FEATURE_ACTIVE when CET is disabled d5db2ef4ce x86/cet: Check legacy shadow stack applications f258b3fa5a x86/cet: Don't assume that SHSTK implies IBT 27da1273b9 x86/cet: Check user_shstk in /proc/cpuinfo 058c4723cb Update syscall lists for Linux 6.7 ffdf8ef6c1 Update syscall lists for Linux 6.6 d2d1978e9a Remove installed header rule on $(..)include/%.h e4bd849a5d debug: Fix tst-longjmp_chk3 build failure on Hurd 4db5358c9c debug: Wire up tst-longjmp_chk3 1fc2002d60 debug: Adapt fortify tests to libsupport 9bb20abcaa x86-64: Save APX registers in ld.so trampoline 768103fa49 i386: Remove CET support c69b88fc71 x86-64: Add GLIBC_ABI_DT_X86_64_PLT [BZ #33212] 1bdce25455 elf: Handle ld.so with LOAD segment gaps in _dl_find_object (bug 31943) c35196339c elf: Extract rtld_setup_phdr function from dl_main 93fa28a752 elf: Do not add a copy of _dl_find_object to libc.so 40aa3ade66 arm: Use _dl_find_object on __gnu_Unwind_Find_exidx (BZ 31405) --- ...nstalled-header-rule-on-.-include-.h.patch | 68 + Update-syscall-lists-for-Linux-6.6.patch | 406 ++++ Update-syscall-lists-for-Linux-6.7.patch | 671 +++++++ ..._object-on-__gnu_Unwind_Find_exidx-B.patch | 202 ++ debug-Adapt-fortify-tests-to-libsupport.patch | 213 +++ ...t-longjmp_chk3-build-failure-on-Hurd.patch | 27 + debug-Wire-up-tst-longjmp_chk3.patch | 72 + ...a-copy-of-_dl_find_object-to-libc.so.patch | 101 + ...tld_setup_phdr-function-from-dl_main.patch | 94 + ...-with-LOAD-segment-gaps-in-_dl_find_.patch | 476 +++++ glibc.spec | 48 +- i386-Fail-if-configured-with-enable-cet.patch | 101 + i386-Ignore-enable-cet.patch | 403 ++++ i386-Remove-CET-support-bits.patch | 304 +++ i386-Remove-CET-support.patch | 1638 +++++++++++++++++ ...shadow-stack-during-startup-for-Linu.patch | 80 + ...Add-GLIBC_ABI_DT_X86_64_PLT-BZ-33212.patch | 82 + ...state-buffer-space-for-RDI-RSI-and-R.patch | 259 +++ ...move-sysdeps-x86_64-x32-dl-machine.h.patch | 181 ++ ...ve-APX-registers-in-ld.so-trampoline.patch | 85 + ...l_tlsdesc_dynamic-to-preserve-AMX-re.patch | 520 ++++++ ...t-Check-the-restore-token-in-longjmp.patch | 325 ++++ ...CET-feature-check-specific-to-Linux-.patch | 253 +++ x86-64-cet-Move-check-cet.awk-to-x86_64.patch | 33 + ...ove-dl-cet.-ch-to-x86_64-directories.patch | 164 ++ x86-Modularize-sysdeps-x86-dl-cet.c.patch | 513 ++++++ x86-Move-CET-infrastructure-to-x86_64.patch | 950 ++++++++++ ...lsdesc_dynamic-to-preserve-caller-sa.patch | 1469 +++++++++++++++ ...protection-none-before-fcf-protectio.patch | 85 + ...s-for-GLIBC_TUNABLES-glibc.cpu.hwcap.patch | 83 + ...PU_FEATURE_ACTIVE-in-permissive-mode.patch | 51 + ...U_FEATURE_ACTIVE-when-CET-is-disable.patch | 63 + ...ature_1-in-TCB-for-active-IBT-and-SH.patch | 91 + ...eck-legacy-shadow-stack-applications.patch | 211 +++ ...gacy-shadow-stack-code-in-.init_arra.patch | 458 +++++ ...cet-Check-user_shstk-in-proc-cpuinfo.patch | 29 + ...-Don-t-assume-that-SHSTK-implies-IBT.patch | 100 + ...t-disable-CET-if-not-single-threaded.patch | 55 + x86-cet-Don-t-set-CET-active-by-default.patch | 78 + ...t-Enable-shadow-stack-during-startup.patch | 512 ++++++ ...Run-some-CET-tests-with-shadow-stack.patch | 104 ++ ...h-Linux-kernel-6.6-shadow-stack-inte.patch | 577 ++++++ x86-cet-Update-tst-cet-vfork-1.patch | 105 ++ x86-cet-fix-shadow-stack-test-scripts.patch | 64 + 44 files changed, 12403 insertions(+), 1 deletion(-) create mode 100644 Remove-installed-header-rule-on-.-include-.h.patch create mode 100644 Update-syscall-lists-for-Linux-6.6.patch create mode 100644 Update-syscall-lists-for-Linux-6.7.patch create mode 100644 arm-Use-_dl_find_object-on-__gnu_Unwind_Find_exidx-B.patch create mode 100644 debug-Adapt-fortify-tests-to-libsupport.patch create mode 100644 debug-Fix-tst-longjmp_chk3-build-failure-on-Hurd.patch create mode 100644 debug-Wire-up-tst-longjmp_chk3.patch create mode 100644 elf-Do-not-add-a-copy-of-_dl_find_object-to-libc.so.patch create mode 100644 elf-Extract-rtld_setup_phdr-function-from-dl_main.patch create mode 100644 elf-Handle-ld.so-with-LOAD-segment-gaps-in-_dl_find_.patch create mode 100644 i386-Fail-if-configured-with-enable-cet.patch create mode 100644 i386-Ignore-enable-cet.patch create mode 100644 i386-Remove-CET-support-bits.patch create mode 100644 i386-Remove-CET-support.patch create mode 100644 x32-cet-Support-shadow-stack-during-startup-for-Linu.patch create mode 100644 x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-BZ-33212.patch create mode 100644 x86-64-Allocate-state-buffer-space-for-RDI-RSI-and-R.patch create mode 100644 x86-64-Remove-sysdeps-x86_64-x32-dl-machine.h.patch create mode 100644 x86-64-Save-APX-registers-in-ld.so-trampoline.patch create mode 100644 x86-64-Update-_dl_tlsdesc_dynamic-to-preserve-AMX-re.patch create mode 100644 x86-64-cet-Check-the-restore-token-in-longjmp.patch create mode 100644 x86-64-cet-Make-CET-feature-check-specific-to-Linux-.patch create mode 100644 x86-64-cet-Move-check-cet.awk-to-x86_64.patch create mode 100644 x86-64-cet-Move-dl-cet.-ch-to-x86_64-directories.patch create mode 100644 x86-Modularize-sysdeps-x86-dl-cet.c.patch create mode 100644 x86-Move-CET-infrastructure-to-x86_64.patch create mode 100644 x86-Update-_dl_tlsdesc_dynamic-to-preserve-caller-sa.patch create mode 100644 x86-cet-Add-fcf-protection-none-before-fcf-protectio.patch create mode 100644 x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hwcap.patch create mode 100644 x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mode.patch create mode 100644 x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disable.patch create mode 100644 x86-cet-Check-feature_1-in-TCB-for-active-IBT-and-SH.patch create mode 100644 x86-cet-Check-legacy-shadow-stack-applications.patch create mode 100644 x86-cet-Check-legacy-shadow-stack-code-in-.init_arra.patch create mode 100644 x86-cet-Check-user_shstk-in-proc-cpuinfo.patch create mode 100644 x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch create mode 100644 x86-cet-Don-t-disable-CET-if-not-single-threaded.patch create mode 100644 x86-cet-Don-t-set-CET-active-by-default.patch create mode 100644 x86-cet-Enable-shadow-stack-during-startup.patch create mode 100644 x86-cet-Run-some-CET-tests-with-shadow-stack.patch create mode 100644 x86-cet-Sync-with-Linux-kernel-6.6-shadow-stack-inte.patch create mode 100644 x86-cet-Update-tst-cet-vfork-1.patch create mode 100644 x86-cet-fix-shadow-stack-test-scripts.patch diff --git a/Remove-installed-header-rule-on-.-include-.h.patch b/Remove-installed-header-rule-on-.-include-.h.patch new file mode 100644 index 0000000..116d61d --- /dev/null +++ b/Remove-installed-header-rule-on-.-include-.h.patch @@ -0,0 +1,68 @@ +From d2d1978e9a5663fbcfd7daa54bbfd2f1eb6cb45b Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 9 Jan 2024 10:25:20 -0800 +Subject: [PATCH] Remove installed header rule on $(..)include/%.h + +On x86-64 machine with + +[hjl@gnu-cfl-3 x86-glibc]$ ls -l /usr/include/asm/prctl.h sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h +-rw-r--r-- 1 hjl hjl 825 Jan 9 09:41 sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h +-rw-r--r-- 1 root root 1170 Nov 27 16:00 /usr/include/asm/prctl.h +[hjl@gnu-cfl-3 x86-glibc]$ + +glibc configured with --enable-cet build failed: + +make[2]: Entering directory '/export/gnu/import/git/gitlab/x86-glibc/iconv' +../Makerules:327: update target +'/export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/gnu/lib-names-64.h' +due to: /export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/gnu/lib-names-64.stmp +: +../Makeconfig:1216: update target +'/export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/libc-modules.h' +due to: /export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/libc-modules.stmp +: +../Makerules:1126: update target '/usr/include/asm/prctl.h' due to: +../sysdeps/unix/sysv/linux/x86_64/64/../include/asm/prctl.h +force-install +/usr/bin/install -c -m 644 +../sysdeps/unix/sysv/linux/x86_64/64/../include/asm/prctl.h +/usr/include/asm/prctl.h +/usr/bin/install: cannot remove '/usr/include/asm/prctl.h': Permission denied +make[2]: *** [../Makerules:1126: /usr/include/asm/prctl.h] Error 1 +make[2]: Leaving directory '/export/gnu/import/git/gitlab/x86-glibc/iconv' +make[1]: *** [Makefile:484: iconv/subdir_lib] Error 2 +make[1]: Leaving directory '/export/gnu/import/git/gitlab/x86-glibc' +make: *** [Makefile:9: all] Error 2 + +This is triggered by the rule in Makerules: + +$(inst_includedir)/%.h: $(..)include/%.h $(+force) + $(do-install) + +Since no files under include/ should be installed, remove it from +Makerules. + +Tested it on x86-64. There are no differences in the installed header +files. + +(cherry picked from commit 1eae989cb7632760fd6f4008be73549da861b202) +--- + Makerules | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/Makerules b/Makerules +index 018780c818..be692d4fcb 100644 +--- a/Makerules ++++ b/Makerules +@@ -1122,8 +1122,6 @@ $(inst_includedir)/%.h: $(common-objpfx)%.h $(+force) + $(do-install) + $(inst_includedir)/%.h: %.h $(+force) + $(do-install) +-$(inst_includedir)/%.h: $(..)include/%.h $(+force) +- $(do-install) + headers-nonh := $(filter-out %.h,$(headers)) + ifdef headers-nonh + $(addprefix $(inst_includedir)/,$(headers-nonh)): $(inst_includedir)/%: \ +-- +2.27.0 + diff --git a/Update-syscall-lists-for-Linux-6.6.patch b/Update-syscall-lists-for-Linux-6.6.patch new file mode 100644 index 0000000..dcacdb2 --- /dev/null +++ b/Update-syscall-lists-for-Linux-6.6.patch @@ -0,0 +1,406 @@ +From ffdf8ef6c12e2fe887d3b8be708884b0279c2871 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Tue, 31 Oct 2023 13:32:33 -0300 +Subject: [PATCH] Update syscall lists for Linux 6.6 + +Linux 6.6 has one new syscall for all architectures, fchmodat2, and +the map_shadow_stack on x86_64. + +(cherry picked from commit 582383b37d95b133c1ee6855ffaa2b1f5cb3d3b8) +--- + sysdeps/unix/sysv/linux/aarch64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/alpha/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/arc/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/arm/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/csky/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/hppa/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/i386/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/ia64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/loongarch/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/m68k/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/microblaze/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/nios2/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/or1k/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/sh/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/syscall-names.list | 6 ++++-- + sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h | 2 ++ + sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h | 1 + + 28 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index 8f21ee66a0..746991aa2f 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -44,6 +44,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl 25 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index c5802a5fec..32efe51267 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -56,6 +56,7 @@ + #define __NR_fchdir 13 + #define __NR_fchmod 124 + #define __NR_fchmodat 461 ++#define __NR_fchmodat2 562 + #define __NR_fchown 123 + #define __NR_fchownat 453 + #define __NR_fcntl 92 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index f23f9e1154..1d2879e877 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -48,6 +48,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl64 25 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 7edf574899..6711981e78 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -64,6 +64,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 333 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchown32 207 + #define __NR_fchownat 325 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index d74a06e063..92d9a703ea 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -50,6 +50,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl64 25 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index 5568b94cd3..fbac124b70 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -63,6 +63,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 286 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchownat 278 + #define __NR_fcntl 55 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 3af21a15cb..8961788a96 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -67,6 +67,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 306 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchown32 207 + #define __NR_fchownat 298 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index 39b270e642..1ef762d693 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -55,6 +55,7 @@ + #define __NR_fchdir 1035 + #define __NR_fchmod 1099 + #define __NR_fchmodat 1292 ++#define __NR_fchmodat2 1476 + #define __NR_fchown 1100 + #define __NR_fchownat 1284 + #define __NR_fcntl 1066 +diff --git a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h b/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h +index fdefe8bb6f..3664e6f7c8 100644 +--- a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h +@@ -44,6 +44,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl 25 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index 315e49cd33..2053d5d392 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -67,6 +67,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 299 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchown32 207 + #define __NR_fchownat 291 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index 54af12780c..6865b1693c 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -67,6 +67,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 306 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchown32 207 + #define __NR_fchownat 298 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index a2aa1ffa1b..b13ace8e1c 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -67,6 +67,7 @@ + #define __NR_fchdir 4133 + #define __NR_fchmod 4094 + #define __NR_fchmodat 4299 ++#define __NR_fchmodat2 4452 + #define __NR_fchown 4095 + #define __NR_fchownat 4291 + #define __NR_fcntl 4055 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 5bec858040..b7a7c0dfa7 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -64,6 +64,7 @@ + #define __NR_fchdir 6079 + #define __NR_fchmod 6089 + #define __NR_fchmodat 6262 ++#define __NR_fchmodat2 6452 + #define __NR_fchown 6091 + #define __NR_fchownat 6254 + #define __NR_fcntl 6070 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index 0166371ee2..e5d7f91f48 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -59,6 +59,7 @@ + #define __NR_fchdir 5079 + #define __NR_fchmod 5089 + #define __NR_fchmodat 5258 ++#define __NR_fchmodat2 5452 + #define __NR_fchown 5091 + #define __NR_fchownat 5250 + #define __NR_fcntl 5070 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 29a4cfa988..89950cc33a 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -49,6 +49,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl64 25 +diff --git a/sysdeps/unix/sysv/linux/or1k/arch-syscall.h b/sysdeps/unix/sysv/linux/or1k/arch-syscall.h +index f5a3729663..4c07d9c204 100644 +--- a/sysdeps/unix/sysv/linux/or1k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/or1k/arch-syscall.h +@@ -49,6 +49,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl64 25 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index 3a212a0269..64683bcb76 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -66,6 +66,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 297 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchownat 289 + #define __NR_fcntl 55 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index 1038ead227..af1bbf32e8 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -60,6 +60,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 297 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchownat 289 + #define __NR_fcntl 55 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 57b043ffb5..56e3088cbf 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -43,6 +43,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl64 25 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 1041a0f8c9..508161b47a 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -44,6 +44,7 @@ + #define __NR_fchdir 50 + #define __NR_fchmod 52 + #define __NR_fchmodat 53 ++#define __NR_fchmodat2 452 + #define __NR_fchown 55 + #define __NR_fchownat 54 + #define __NR_fcntl 25 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index 70d4c6782e..1498ebf42e 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -65,6 +65,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 299 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchown32 207 + #define __NR_fchownat 291 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 65a8a9e316..624d71b56d 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -56,6 +56,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 299 ++#define __NR_fchmodat2 452 + #define __NR_fchown 207 + #define __NR_fchownat 291 + #define __NR_fcntl 55 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 94aad0f119..37211f5f8c 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -64,6 +64,7 @@ + #define __NR_fchdir 133 + #define __NR_fchmod 94 + #define __NR_fchmodat 306 ++#define __NR_fchmodat2 452 + #define __NR_fchown 95 + #define __NR_fchown32 207 + #define __NR_fchownat 298 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index d630306c75..8093abcc9c 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -66,6 +66,7 @@ + #define __NR_fchdir 176 + #define __NR_fchmod 124 + #define __NR_fchmodat 295 ++#define __NR_fchmodat2 452 + #define __NR_fchown 123 + #define __NR_fchown32 32 + #define __NR_fchownat 287 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 930f29b4d2..d25ccfb571 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -60,6 +60,7 @@ + #define __NR_fchdir 176 + #define __NR_fchmod 124 + #define __NR_fchmodat 295 ++#define __NR_fchmodat2 452 + #define __NR_fchown 123 + #define __NR_fchownat 287 + #define __NR_fcntl 92 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index cf6f70ecd9..c3627fcd7f 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 6.5. +-kernel 6.5 ++# The list of system calls is current as of Linux 6.6. ++kernel 6.6 + + FAST_atomic_update + FAST_cmpxchg +@@ -117,6 +117,7 @@ fanotify_mark + fchdir + fchmod + fchmodat ++fchmodat2 + fchown + fchown32 + fchownat +@@ -246,6 +247,7 @@ lsetxattr + lstat + lstat64 + madvise ++map_shadow_stack + mbind + membarrier + memfd_create +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 58646cf0bd..5e4c9e901c 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -59,6 +59,7 @@ + #define __NR_fchdir 81 + #define __NR_fchmod 91 + #define __NR_fchmodat 268 ++#define __NR_fchmodat2 452 + #define __NR_fchown 93 + #define __NR_fchownat 260 + #define __NR_fcntl 72 +@@ -153,6 +154,7 @@ + #define __NR_lsetxattr 189 + #define __NR_lstat 6 + #define __NR_madvise 28 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 237 + #define __NR_membarrier 324 + #define __NR_memfd_create 319 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 604bcdfa5b..dd5e196272 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -55,6 +55,7 @@ + #define __NR_fchdir 1073741905 + #define __NR_fchmod 1073741915 + #define __NR_fchmodat 1073742092 ++#define __NR_fchmodat2 1073742276 + #define __NR_fchown 1073741917 + #define __NR_fchownat 1073742084 + #define __NR_fcntl 1073741896 +-- +2.27.0 + diff --git a/Update-syscall-lists-for-Linux-6.7.patch b/Update-syscall-lists-for-Linux-6.7.patch new file mode 100644 index 0000000..9f9a93f --- /dev/null +++ b/Update-syscall-lists-for-Linux-6.7.patch @@ -0,0 +1,671 @@ +From 058c4723cbc37176497fa69148451c70d62d0e78 Mon Sep 17 00:00:00 2001 +From: Joseph Myers +Date: Wed, 17 Jan 2024 15:38:54 +0000 +Subject: [PATCH] Update syscall lists for Linux 6.7 + +Linux 6.7 adds the futex_requeue, futex_wait and futex_wake syscalls, +and enables map_shadow_stack for architectures previously missing it. +Update syscall-names.list and regenerate the arch-syscall.h headers +with build-many-glibcs.py update-syscalls. + +Tested with build-many-glibcs.py. + +(cherry picked from commit df11c05be91fda5ef490c76fd0d4a53821750116) +--- + sysdeps/unix/sysv/linux/aarch64/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/alpha/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/arc/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/arm/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/csky/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/hppa/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/i386/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/loongarch/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/m68k/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/microblaze/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/nios2/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/or1k/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/sh/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h | 4 ++++ + sysdeps/unix/sysv/linux/syscall-names.list | 7 +++++-- + sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h | 3 +++ + sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h | 3 +++ + 27 files changed, 107 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index 746991aa2f..1713897f85 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -64,7 +64,10 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -126,6 +129,7 @@ + #define __NR_lseek 62 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index 32efe51267..5457d2d8ae 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -80,7 +80,10 @@ + #define __NR_fsync 95 + #define __NR_ftruncate 130 + #define __NR_futex 394 ++#define __NR_futex_requeue 566 ++#define __NR_futex_wait 565 + #define __NR_futex_waitv 559 ++#define __NR_futex_wake 564 + #define __NR_futimesat 454 + #define __NR_get_kernel_syms 309 + #define __NR_get_mempolicy 430 +@@ -156,6 +159,7 @@ + #define __NR_lstat 68 + #define __NR_lstat64 426 + #define __NR_madvise 75 ++#define __NR_map_shadow_stack 563 + #define __NR_mbind 429 + #define __NR_membarrier 517 + #define __NR_memfd_create 512 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index 1d2879e877..a66471c83a 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -66,8 +66,11 @@ + #define __NR_fstatfs64 44 + #define __NR_fsync 82 + #define __NR_ftruncate64 46 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -130,6 +133,7 @@ + #define __NR_lremovexattr 15 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 6711981e78..74a57f4520 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -91,8 +91,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 240 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 326 + #define __NR_get_mempolicy 320 + #define __NR_get_robust_list 339 +@@ -170,6 +173,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 220 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 319 + #define __NR_membarrier 389 + #define __NR_memfd_create 385 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 92d9a703ea..ba7632e018 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -71,8 +71,11 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex 98 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -135,6 +138,7 @@ + #define __NR_lremovexattr 15 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index fbac124b70..483706de9b 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -89,8 +89,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 200 + #define __NR_futex 210 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 279 + #define __NR_get_mempolicy 261 + #define __NR_get_robust_list 290 +@@ -161,6 +164,7 @@ + #define __NR_lstat 84 + #define __NR_lstat64 198 + #define __NR_madvise 119 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 260 + #define __NR_membarrier 343 + #define __NR_memfd_create 340 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 8961788a96..21c1308bb3 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -95,8 +95,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 240 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 299 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 275 +@@ -183,6 +186,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 219 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 274 + #define __NR_membarrier 375 + #define __NR_memfd_create 356 +diff --git a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h b/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h +index 3664e6f7c8..f6a434630e 100644 +--- a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h +@@ -63,7 +63,10 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -124,6 +127,7 @@ + #define __NR_lseek 62 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index 2053d5d392..6d788e3440 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -94,8 +94,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 235 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +@@ -177,6 +180,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 238 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 268 + #define __NR_membarrier 374 + #define __NR_memfd_create 353 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index 6865b1693c..91e1630f7b 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -95,8 +95,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 240 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 299 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 275 +@@ -183,6 +186,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 219 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 274 + #define __NR_membarrier 390 + #define __NR_memfd_create 386 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index b13ace8e1c..d75af97467 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -94,8 +94,11 @@ + #define __NR_ftruncate 4093 + #define __NR_ftruncate64 4212 + #define __NR_futex 4238 ++#define __NR_futex_requeue 4456 + #define __NR_futex_time64 4422 ++#define __NR_futex_wait 4455 + #define __NR_futex_waitv 4449 ++#define __NR_futex_wake 4454 + #define __NR_futimesat 4292 + #define __NR_get_kernel_syms 4130 + #define __NR_get_mempolicy 4269 +@@ -173,6 +176,7 @@ + #define __NR_lstat 4107 + #define __NR_lstat64 4214 + #define __NR_madvise 4218 ++#define __NR_map_shadow_stack 4453 + #define __NR_mbind 4268 + #define __NR_membarrier 4358 + #define __NR_memfd_create 4354 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index b7a7c0dfa7..05bf7d251d 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -87,8 +87,11 @@ + #define __NR_fsync 6072 + #define __NR_ftruncate 6075 + #define __NR_futex 6194 ++#define __NR_futex_requeue 6456 + #define __NR_futex_time64 6422 ++#define __NR_futex_wait 6455 + #define __NR_futex_waitv 6449 ++#define __NR_futex_wake 6454 + #define __NR_futimesat 6255 + #define __NR_get_kernel_syms 6170 + #define __NR_get_mempolicy 6232 +@@ -159,6 +162,7 @@ + #define __NR_lsetxattr 6181 + #define __NR_lstat 6006 + #define __NR_madvise 6027 ++#define __NR_map_shadow_stack 6453 + #define __NR_mbind 6231 + #define __NR_membarrier 6322 + #define __NR_memfd_create 6318 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index e5d7f91f48..41ffaf3255 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -80,7 +80,10 @@ + #define __NR_fsync 5072 + #define __NR_ftruncate 5075 + #define __NR_futex 5194 ++#define __NR_futex_requeue 5456 ++#define __NR_futex_wait 5455 + #define __NR_futex_waitv 5449 ++#define __NR_futex_wake 5454 + #define __NR_futimesat 5251 + #define __NR_get_kernel_syms 5170 + #define __NR_get_mempolicy 5228 +@@ -150,6 +153,7 @@ + #define __NR_lsetxattr 5181 + #define __NR_lstat 5006 + #define __NR_madvise 5027 ++#define __NR_map_shadow_stack 5453 + #define __NR_mbind 5227 + #define __NR_membarrier 5318 + #define __NR_memfd_create 5314 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 89950cc33a..d94e7e9ee9 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -70,8 +70,11 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex 98 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -134,6 +137,7 @@ + #define __NR_lremovexattr 15 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/or1k/arch-syscall.h b/sysdeps/unix/sysv/linux/or1k/arch-syscall.h +index 4c07d9c204..39295a6f94 100644 +--- a/sysdeps/unix/sysv/linux/or1k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/or1k/arch-syscall.h +@@ -70,8 +70,11 @@ + #define __NR_fsync 82 + #define __NR_ftruncate64 46 + #define __NR_futex 98 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -134,6 +137,7 @@ + #define __NR_lremovexattr 15 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index 64683bcb76..b5522e8889 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -93,8 +93,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 221 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 290 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 260 +@@ -173,6 +176,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 205 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 259 + #define __NR_membarrier 365 + #define __NR_memfd_create 360 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index af1bbf32e8..162d782ae6 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -83,7 +83,10 @@ + #define __NR_ftime 35 + #define __NR_ftruncate 93 + #define __NR_futex 221 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 290 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 260 +@@ -160,6 +163,7 @@ + #define __NR_lsetxattr 210 + #define __NR_lstat 107 + #define __NR_madvise 205 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 259 + #define __NR_membarrier 365 + #define __NR_memfd_create 360 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 56e3088cbf..013222e5de 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -61,8 +61,11 @@ + #define __NR_fstatfs64 44 + #define __NR_fsync 82 + #define __NR_ftruncate64 46 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -121,6 +124,7 @@ + #define __NR_lremovexattr 15 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 508161b47a..d03dad8200 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -64,7 +64,10 @@ + #define __NR_fsync 82 + #define __NR_ftruncate 46 + #define __NR_futex 98 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_get_mempolicy 236 + #define __NR_get_robust_list 100 + #define __NR_getcpu 168 +@@ -126,6 +129,7 @@ + #define __NR_lseek 62 + #define __NR_lsetxattr 6 + #define __NR_madvise 233 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index 1498ebf42e..98e6b68b31 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -92,8 +92,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 238 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +@@ -177,6 +180,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 219 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 268 + #define __NR_membarrier 356 + #define __NR_memfd_create 350 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 624d71b56d..951fbd7c97 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -78,7 +78,10 @@ + #define __NR_fsync 118 + #define __NR_ftruncate 93 + #define __NR_futex 238 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 292 + #define __NR_get_kernel_syms 130 + #define __NR_get_mempolicy 269 +@@ -151,6 +154,7 @@ + #define __NR_lsetxattr 225 + #define __NR_lstat 107 + #define __NR_madvise 219 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 268 + #define __NR_membarrier 356 + #define __NR_memfd_create 350 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 37211f5f8c..6b4418bcae 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -91,8 +91,11 @@ + #define __NR_ftruncate 93 + #define __NR_ftruncate64 194 + #define __NR_futex 240 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 299 + #define __NR_get_mempolicy 275 + #define __NR_get_robust_list 312 +@@ -170,6 +173,7 @@ + #define __NR_lstat 107 + #define __NR_lstat64 196 + #define __NR_madvise 219 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 274 + #define __NR_membarrier 378 + #define __NR_memfd_create 374 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 8093abcc9c..4f9460b1a3 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -93,8 +93,11 @@ + #define __NR_ftruncate 130 + #define __NR_ftruncate64 84 + #define __NR_futex 142 ++#define __NR_futex_requeue 456 + #define __NR_futex_time64 422 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 288 + #define __NR_get_kernel_syms 223 + #define __NR_get_mempolicy 304 +@@ -175,6 +178,7 @@ + #define __NR_lstat 40 + #define __NR_lstat64 132 + #define __NR_madvise 75 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 303 + #define __NR_membarrier 351 + #define __NR_memfd_create 348 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index d25ccfb571..129ce50646 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -84,7 +84,10 @@ + #define __NR_fsync 95 + #define __NR_ftruncate 130 + #define __NR_futex 142 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 288 + #define __NR_get_kernel_syms 223 + #define __NR_get_mempolicy 304 +@@ -158,6 +161,7 @@ + #define __NR_lstat 40 + #define __NR_lstat64 132 + #define __NR_madvise 75 ++#define __NR_map_shadow_stack 453 + #define __NR_mbind 303 + #define __NR_membarrier 351 + #define __NR_memfd_create 348 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index c3627fcd7f..3ce7f481d2 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 6.6. +-kernel 6.6 ++# The list of system calls is current as of Linux 6.7. ++kernel 6.7 + + FAST_atomic_update + FAST_cmpxchg +@@ -147,8 +147,11 @@ ftime + ftruncate + ftruncate64 + futex ++futex_requeue + futex_time64 ++futex_wait + futex_waitv ++futex_wake + futimesat + get_kernel_syms + get_mempolicy +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 5e4c9e901c..4fa5b942c5 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -80,7 +80,10 @@ + #define __NR_fsync 74 + #define __NR_ftruncate 77 + #define __NR_futex 202 ++#define __NR_futex_requeue 456 ++#define __NR_futex_wait 455 + #define __NR_futex_waitv 449 ++#define __NR_futex_wake 454 + #define __NR_futimesat 261 + #define __NR_get_kernel_syms 177 + #define __NR_get_mempolicy 239 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index dd5e196272..b9db8bc5be 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -76,7 +76,10 @@ + #define __NR_fsync 1073741898 + #define __NR_ftruncate 1073741901 + #define __NR_futex 1073742026 ++#define __NR_futex_requeue 1073742280 ++#define __NR_futex_wait 1073742279 + #define __NR_futex_waitv 1073742273 ++#define __NR_futex_wake 1073742278 + #define __NR_futimesat 1073742085 + #define __NR_get_mempolicy 1073742063 + #define __NR_get_robust_list 1073742355 +-- +2.27.0 + diff --git a/arm-Use-_dl_find_object-on-__gnu_Unwind_Find_exidx-B.patch b/arm-Use-_dl_find_object-on-__gnu_Unwind_Find_exidx-B.patch new file mode 100644 index 0000000..6ad8445 --- /dev/null +++ b/arm-Use-_dl_find_object-on-__gnu_Unwind_Find_exidx-B.patch @@ -0,0 +1,202 @@ +From 40aa3ade66cbaf5a9be9e68c525f04ab193ceea1 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Thu, 22 Feb 2024 10:42:55 -0300 +Subject: [PATCH] arm: Use _dl_find_object on __gnu_Unwind_Find_exidx (BZ + 31405) + +Instead of __dl_iterate_phdr. On ARM dlfo_eh_frame/dlfo_eh_count +maps to PT_ARM_EXIDX vaddr start / length. + +On a Neoverse N1 machine with 160 cores, the following program: + + $ cat test.c + #include + #include + #include + + enum { + niter = 1024, + ntimes = 128, + }; + + static void * + tf (void *arg) + { + int a = (int) arg; + + for (int i = 0; i < niter; i++) + { + void *p[ntimes]; + for (int j = 0; j < ntimes; j++) + p[j] = malloc (a * 128); + for (int j = 0; j < ntimes; j++) + free (p[j]); + } + + return NULL; + } + + int main (int argc, char *argv[]) + { + enum { nthreads = 16 }; + pthread_t t[nthreads]; + + for (int i = 0; i < nthreads; i ++) + assert (pthread_create (&t[i], NULL, tf, (void *) i) == 0); + + for (int i = 0; i < nthreads; i++) + { + void *r; + assert (pthread_join (t[i], &r) == 0); + assert (r == NULL); + } + + return 0; + } + $ arm-linux-gnueabihf-gcc -fsanitize=address test.c -o test + +Improves from ~15s to 0.5s. + +Checked on arm-linux-gnueabihf. + +(cherry picked from commit f4c142bb9fe6b02c0af8cfca8a920091e2dba44b) +--- + elf/Makefile | 2 +- + elf/dl-find_object.c | 5 ++-- + include/dlfcn.h | 3 ++- + sysdeps/arm/find_exidx.c | 57 +++------------------------------------- + 4 files changed, 10 insertions(+), 57 deletions(-) + +diff --git a/elf/Makefile b/elf/Makefile +index ff14e80900..59b6ca73c7 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -34,6 +34,7 @@ routines = \ + dl-addr \ + dl-addr-obj \ + dl-early_allocate \ ++ dl-find_object \ + dl-iteratephdr \ + dl-libc \ + dl-origin \ +@@ -60,7 +61,6 @@ dl-routines = \ + dl-deps \ + dl-exception \ + dl-execstack \ +- dl-find_object \ + dl-fini \ + dl-init \ + dl-load \ +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index c1390ee10f..5885655026 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -356,7 +356,7 @@ _dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) + } + + int +-_dl_find_object (void *pc1, struct dl_find_object *result) ++__dl_find_object (void *pc1, struct dl_find_object *result) + { + uintptr_t pc = (uintptr_t) pc1; + +@@ -463,7 +463,8 @@ _dl_find_object (void *pc1, struct dl_find_object *result) + return -1; + } /* Transaction retry loop. */ + } +-rtld_hidden_def (_dl_find_object) ++hidden_def (__dl_find_object) ++weak_alias (__dl_find_object, _dl_find_object) + + /* _dlfo_process_initial is called twice. First to compute the array + sizes from the initial loaded mappings. Second to fill in the +diff --git a/include/dlfcn.h b/include/dlfcn.h +index ae25f05303..f3691439cc 100644 +--- a/include/dlfcn.h ++++ b/include/dlfcn.h +@@ -4,7 +4,8 @@ + #include /* For ElfW. */ + #include + +-rtld_hidden_proto (_dl_find_object) ++extern __typeof (_dl_find_object) __dl_find_object; ++hidden_proto (__dl_find_object) + + /* Internally used flag. */ + #define __RTLD_DLOPEN 0x80000000 +diff --git a/sysdeps/arm/find_exidx.c b/sysdeps/arm/find_exidx.c +index e4ee106fb8..eb56a50dc0 100644 +--- a/sysdeps/arm/find_exidx.c ++++ b/sysdeps/arm/find_exidx.c +@@ -16,64 +16,15 @@ + . */ + + #include +-#include +- +-struct unw_eh_callback_data +-{ +- _Unwind_Ptr pc; +- _Unwind_Ptr exidx_start; +- int exidx_len; +-}; +- +- +-/* Callback to determines if the PC lies within an object, and remember the +- location of the exception index table if it does. */ +- +-static int +-find_exidx_callback (struct dl_phdr_info * info, size_t size, void * ptr) +-{ +- struct unw_eh_callback_data * data; +- const ElfW(Phdr) *phdr; +- int i; +- int match; +- _Unwind_Ptr load_base; +- +- data = (struct unw_eh_callback_data *) ptr; +- load_base = info->dlpi_addr; +- phdr = info->dlpi_phdr; +- +- match = 0; +- for (i = info->dlpi_phnum; i > 0; i--, phdr++) +- { +- if (phdr->p_type == PT_LOAD) +- { +- _Unwind_Ptr vaddr = phdr->p_vaddr + load_base; +- if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz) +- match = 1; +- } +- else if (phdr->p_type == PT_ARM_EXIDX) +- { +- data->exidx_start = (_Unwind_Ptr) (phdr->p_vaddr + load_base); +- data->exidx_len = phdr->p_memsz; +- } +- } +- +- return match; +-} +- + + /* Find the exception index table containing PC. */ + + _Unwind_Ptr + __gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int * pcount) + { +- struct unw_eh_callback_data data; +- +- data.pc = pc; +- data.exidx_start = 0; +- if (__dl_iterate_phdr (find_exidx_callback, &data) <= 0) ++ struct dl_find_object data; ++ if (__dl_find_object ((void *) pc, &data) < 0) + return 0; +- +- *pcount = data.exidx_len / 8; +- return data.exidx_start; ++ *pcount = data.dlfo_eh_count; ++ return (_Unwind_Ptr) data.dlfo_eh_frame; + } +-- +2.27.0 + diff --git a/debug-Adapt-fortify-tests-to-libsupport.patch b/debug-Adapt-fortify-tests-to-libsupport.patch new file mode 100644 index 0000000..6fdb45e --- /dev/null +++ b/debug-Adapt-fortify-tests-to-libsupport.patch @@ -0,0 +1,213 @@ +From 1fc2002d60025143599d0343af80dcfa4585f75a Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Thu, 21 Dec 2023 15:59:15 -0300 +Subject: [PATCH] debug: Adapt fortify tests to libsupport + +Checked on aarch64, armhf, x86_64, and i686. +Reviewed-by: Siddhesh Poyarekar + +(cherry picked from commit 9556acd249687ac562deb6309503165d66eb06fa) +--- + debug/test-stpcpy_chk.c | 2 +- + debug/test-strcpy_chk.c | 2 +- + debug/tst-fortify.c | 55 +++++++++++++++++++++------------------- + debug/tst-longjmp_chk.c | 8 +++--- + debug/tst-longjmp_chk2.c | 6 ++--- + debug/tst-longjmp_chk3.c | 6 ++--- + 6 files changed, 39 insertions(+), 40 deletions(-) + +diff --git a/debug/test-stpcpy_chk.c b/debug/test-stpcpy_chk.c +index 938f3c0ceb..0b9fed49cc 100644 +--- a/debug/test-stpcpy_chk.c ++++ b/debug/test-stpcpy_chk.c +@@ -19,7 +19,7 @@ + #define STRCPY_RESULT(dst, len) ((dst) + (len)) + #define TEST_MAIN + #define TEST_NAME "stpcpy_chk" +-#include "../string/test-string.h" ++#include + + extern void __attribute__ ((noreturn)) __chk_fail (void); + char *simple_stpcpy_chk (char *, const char *, size_t); +diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c +index 792e789e1e..684e0bdd9b 100644 +--- a/debug/test-strcpy_chk.c ++++ b/debug/test-strcpy_chk.c +@@ -20,7 +20,7 @@ + # define STRCPY_RESULT(dst, len) dst + # define TEST_MAIN + # define TEST_NAME "strcpy_chk" +-# include "../string/test-string.h" ++# include + + /* This test case implicitly tests the availability of the __chk_fail + symbol, which is part of the public ABI and may be used +diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c +index 3744aadad4..20e926751a 100644 +--- a/debug/tst-fortify.c ++++ b/debug/tst-fortify.c +@@ -23,6 +23,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -36,6 +37,10 @@ + #include + #include + #include ++#include ++ ++#include ++#include + + #ifndef _GNU_SOURCE + # define MEMPCPY memcpy +@@ -52,15 +57,10 @@ + #define obstack_chunk_alloc malloc + #define obstack_chunk_free free + +-char *temp_filename; +-static void do_prepare (void); +-static int do_test (void); +-#define PREPARE(argc, argv) do_prepare () +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++static char *temp_filename; + + static void +-do_prepare (void) ++do_prepare (int argc, char *argv[]) + { + int temp_fd = create_temp_file ("tst-chk1.", &temp_filename); + if (temp_fd == -1) +@@ -77,10 +77,11 @@ do_prepare (void) + exit (1); + } + } ++#define PREPARE do_prepare + +-volatile int chk_fail_ok; +-volatile int ret; +-jmp_buf chk_fail_buf; ++static volatile int chk_fail_ok; ++static volatile int ret; ++static jmp_buf chk_fail_buf; + + static void + handler (int sig) +@@ -102,22 +103,22 @@ wchar_t wbuf[10]; + #define buf_size sizeof (buf) + #endif + +-volatile size_t l0; +-volatile char *p; +-volatile wchar_t *wp; +-const char *str1 = "JIHGFEDCBA"; +-const char *str2 = "F"; +-const char *str3 = "%s%n%s%n"; +-const char *str4 = "Hello, "; +-const char *str5 = "World!\n"; +-const wchar_t *wstr1 = L"JIHGFEDCBA"; +-const wchar_t *wstr2 = L"F"; +-const wchar_t *wstr3 = L"%s%n%s%n"; +-const wchar_t *wstr4 = L"Hello, "; +-const wchar_t *wstr5 = L"World!\n"; +-char buf2[10] = "%s"; +-int num1 = 67; +-int num2 = 987654; ++static volatile size_t l0; ++static volatile char *p; ++static volatile wchar_t *wp; ++static const char *str1 = "JIHGFEDCBA"; ++static const char *str2 = "F"; ++static const char *str3 = "%s%n%s%n"; ++static const char *str4 = "Hello, "; ++static const char *str5 = "World!\n"; ++static const wchar_t *wstr1 = L"JIHGFEDCBA"; ++static const wchar_t *wstr2 = L"F"; ++static const wchar_t *wstr3 = L"%s%n%s%n"; ++static const wchar_t *wstr4 = L"Hello, "; ++static const wchar_t *wstr5 = L"World!\n"; ++static char buf2[10] = "%s"; ++static int num1 = 67; ++static int num2 = 987654; + + #define FAIL() \ + do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0) +@@ -1815,3 +1816,5 @@ do_test (void) + + return ret; + } ++ ++#include +diff --git a/debug/tst-longjmp_chk.c b/debug/tst-longjmp_chk.c +index e4e93d2a36..37f858606b 100644 +--- a/debug/tst-longjmp_chk.c ++++ b/debug/tst-longjmp_chk.c +@@ -10,11 +10,7 @@ + #include + #include + +- +-static int do_test(void); +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" +- ++#include + + static jmp_buf b; + +@@ -76,3 +72,5 @@ do_test (void) + puts ("second longjmp returned"); + return 1; + } ++ ++#include +diff --git a/debug/tst-longjmp_chk2.c b/debug/tst-longjmp_chk2.c +index 1810ab44d7..7e1ee3edc5 100644 +--- a/debug/tst-longjmp_chk2.c ++++ b/debug/tst-longjmp_chk2.c +@@ -10,9 +10,7 @@ + #include + #include + +-static int do_test (void); +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++#include + + static jmp_buf mainloop; + static sigset_t mainsigset; +@@ -126,3 +124,5 @@ do_test (void) + + return 0; + } ++ ++#include +diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c +index f1e576ad5b..3050806c44 100644 +--- a/debug/tst-longjmp_chk3.c ++++ b/debug/tst-longjmp_chk3.c +@@ -20,10 +20,6 @@ + #include + #include + +-static int do_test (void); +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" +- + static char buf[SIGSTKSZ * 4]; + static jmp_buf jb; + +@@ -83,3 +79,5 @@ do_test (void) + puts ("longjmp returned and shouldn't"); + return 1; + } ++ ++#include +-- +2.27.0 + diff --git a/debug-Fix-tst-longjmp_chk3-build-failure-on-Hurd.patch b/debug-Fix-tst-longjmp_chk3-build-failure-on-Hurd.patch new file mode 100644 index 0000000..3a325bd --- /dev/null +++ b/debug-Fix-tst-longjmp_chk3-build-failure-on-Hurd.patch @@ -0,0 +1,27 @@ +From e4bd849a5d7586a37db3cb0f83e6b4df3d8ef7e4 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Tue, 26 Nov 2024 19:26:13 +0100 +Subject: [PATCH] debug: Fix tst-longjmp_chk3 build failure on Hurd + +Explicitly include for _exit and getpid. + +(cherry picked from commit 4836a9af89f1b4d482e6c72ff67e36226d36434c) +--- + debug/tst-longjmp_chk3.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c +index f1562c4b09..34413e1288 100644 +--- a/debug/tst-longjmp_chk3.c ++++ b/debug/tst-longjmp_chk3.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include + +-- +2.27.0 + diff --git a/debug-Wire-up-tst-longjmp_chk3.patch b/debug-Wire-up-tst-longjmp_chk3.patch new file mode 100644 index 0000000..164703f --- /dev/null +++ b/debug-Wire-up-tst-longjmp_chk3.patch @@ -0,0 +1,72 @@ +From 4db5358c9c101c64128e43943f8e096964b3a921 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Mon, 25 Nov 2024 17:32:54 +0100 +Subject: [PATCH] debug: Wire up tst-longjmp_chk3 + +The test was added in commit ac8cc9e300a002228eb7e660df3e7b333d9a7414 +without all the required Makefile scaffolding. Tweak the test +so that it actually builds (including with dynamic SIGSTKSZ). + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 4b7cfcc3fbfab55a1bbb32a2da69c048060739d6) +--- + debug/Makefile | 1 + + debug/tst-longjmp_chk3.c | 13 +++++++++---- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/debug/Makefile b/debug/Makefile +index 434e52f780..439f860eb1 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -283,6 +283,7 @@ tests = \ + tst-backtrace6 \ + tst-longjmp_chk \ + tst-longjmp_chk2 \ ++ tst-longjmp_chk3 \ + tst-realpath-chk \ + tst-sprintf-fortify-unchecked \ + # tests +diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c +index 3050806c44..f1562c4b09 100644 +--- a/debug/tst-longjmp_chk3.c ++++ b/debug/tst-longjmp_chk3.c +@@ -18,9 +18,12 @@ + + #include + #include ++#include + #include + +-static char buf[SIGSTKSZ * 4]; ++#include ++ ++static char *buf; + static jmp_buf jb; + + static void +@@ -49,8 +52,10 @@ do_test (void) + set_fortify_handler (handler); + + /* Create a valid signal stack and enable it. */ ++ size_t bufsize = SIGSTKSZ * 4; ++ buf = xmalloc (bufsize); + ss.ss_sp = buf; +- ss.ss_size = sizeof (buf); ++ ss.ss_size = bufsize; + ss.ss_flags = 0; + if (sigaltstack (&ss, NULL) < 0) + { +@@ -65,8 +70,8 @@ do_test (void) + + /* Shrink the signal stack so the jmpbuf is now invalid. + We adjust the start & end to handle stacks that grow up & down. */ +- ss.ss_sp = buf + sizeof (buf) / 2; +- ss.ss_size = sizeof (buf) / 4; ++ ss.ss_sp = buf + bufsize / 2; ++ ss.ss_size = bufsize / 4; + if (sigaltstack (&ss, NULL) < 0) + { + printf ("second sigaltstack failed: %m\n"); +-- +2.27.0 + diff --git a/elf-Do-not-add-a-copy-of-_dl_find_object-to-libc.so.patch b/elf-Do-not-add-a-copy-of-_dl_find_object-to-libc.so.patch new file mode 100644 index 0000000..948b0e0 --- /dev/null +++ b/elf-Do-not-add-a-copy-of-_dl_find_object-to-libc.so.patch @@ -0,0 +1,101 @@ +From 93fa28a752a313b28f01a2adc9dc6a84a1da9987 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Sat, 1 Feb 2025 12:37:58 +0100 +Subject: [PATCH] elf: Do not add a copy of _dl_find_object to libc.so + +This reduces code size and dependencies on ld.so internals from +libc.so. + +Fixes commit f4c142bb9fe6b02c0af8cfca8a920091e2dba44b +("arm: Use _dl_find_object on __gnu_Unwind_Find_exidx (BZ 31405)"). + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 96429bcc91a14f71b177ddc5e716de3069060f2c) +--- + elf/Makefile | 2 +- + elf/dl-find_object.c | 5 ++--- + include/dlfcn.h | 3 +-- + sysdeps/arm/find_exidx.c | 3 ++- + 4 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/elf/Makefile b/elf/Makefile +index 59b6ca73c7..ff14e80900 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -34,7 +34,6 @@ routines = \ + dl-addr \ + dl-addr-obj \ + dl-early_allocate \ +- dl-find_object \ + dl-iteratephdr \ + dl-libc \ + dl-origin \ +@@ -61,6 +60,7 @@ dl-routines = \ + dl-deps \ + dl-exception \ + dl-execstack \ ++ dl-find_object \ + dl-fini \ + dl-init \ + dl-load \ +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 5885655026..c1390ee10f 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -356,7 +356,7 @@ _dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) + } + + int +-__dl_find_object (void *pc1, struct dl_find_object *result) ++_dl_find_object (void *pc1, struct dl_find_object *result) + { + uintptr_t pc = (uintptr_t) pc1; + +@@ -463,8 +463,7 @@ __dl_find_object (void *pc1, struct dl_find_object *result) + return -1; + } /* Transaction retry loop. */ + } +-hidden_def (__dl_find_object) +-weak_alias (__dl_find_object, _dl_find_object) ++rtld_hidden_def (_dl_find_object) + + /* _dlfo_process_initial is called twice. First to compute the array + sizes from the initial loaded mappings. Second to fill in the +diff --git a/include/dlfcn.h b/include/dlfcn.h +index f3691439cc..ae25f05303 100644 +--- a/include/dlfcn.h ++++ b/include/dlfcn.h +@@ -4,8 +4,7 @@ + #include /* For ElfW. */ + #include + +-extern __typeof (_dl_find_object) __dl_find_object; +-hidden_proto (__dl_find_object) ++rtld_hidden_proto (_dl_find_object) + + /* Internally used flag. */ + #define __RTLD_DLOPEN 0x80000000 +diff --git a/sysdeps/arm/find_exidx.c b/sysdeps/arm/find_exidx.c +index eb56a50dc0..f23c6e8a19 100644 +--- a/sysdeps/arm/find_exidx.c ++++ b/sysdeps/arm/find_exidx.c +@@ -15,6 +15,7 @@ + License along with the GNU C Library. If not, see + . */ + ++#include + #include + + /* Find the exception index table containing PC. */ +@@ -23,7 +24,7 @@ _Unwind_Ptr + __gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int * pcount) + { + struct dl_find_object data; +- if (__dl_find_object ((void *) pc, &data) < 0) ++ if (GLRO(dl_find_object) ((void *) pc, &data) < 0) + return 0; + *pcount = data.dlfo_eh_count; + return (_Unwind_Ptr) data.dlfo_eh_frame; +-- +2.27.0 + diff --git a/elf-Extract-rtld_setup_phdr-function-from-dl_main.patch b/elf-Extract-rtld_setup_phdr-function-from-dl_main.patch new file mode 100644 index 0000000..23c15dd --- /dev/null +++ b/elf-Extract-rtld_setup_phdr-function-from-dl_main.patch @@ -0,0 +1,94 @@ +From c35196339c949cf1b458978a4d95233bf8508b59 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Fri, 1 Aug 2025 10:20:23 +0200 +Subject: [PATCH] elf: Extract rtld_setup_phdr function from dl_main + +Remove historic binutils reference from comment and update +how this data is used by applications. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 2cac9559e06044ba520e785c151fbbd25011865f) +--- + elf/rtld.c | 59 +++++++++++++++++++++++++++++------------------------- + 1 file changed, 32 insertions(+), 27 deletions(-) + +diff --git a/elf/rtld.c b/elf/rtld.c +index b58f3e4aca..8b7b0ff484 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1290,6 +1290,37 @@ rtld_setup_main_map (struct link_map *main_map) + return has_interp; + } + ++/* Set up the program header information for the dynamic linker ++ itself. It can be accessed via _r_debug and dl_iterate_phdr ++ callbacks. */ ++static void ++rtld_setup_phdr (void) ++{ ++ /* Starting from binutils-2.23, the linker will define the magic ++ symbol __ehdr_start to point to our own ELF header if it is ++ visible in a segment that also includes the phdrs. */ ++ ++ const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start; ++ assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); ++ assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); ++ ++ const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff; ++ ++ GL(dl_rtld_map).l_phdr = rtld_phdr; ++ GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; ++ ++ ++ /* PT_GNU_RELRO is usually the last phdr. */ ++ size_t cnt = rtld_ehdr->e_phnum; ++ while (cnt-- > 0) ++ if (rtld_phdr[cnt].p_type == PT_GNU_RELRO) ++ { ++ GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr; ++ GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz; ++ break; ++ } ++} ++ + /* 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 +@@ -1755,33 +1786,7 @@ dl_main (const ElfW(Phdr) *phdr, + ++GL(dl_ns)[LM_ID_BASE]._ns_nloaded; + ++GL(dl_load_adds); + +- /* Starting from binutils-2.23, the linker will define the magic symbol +- __ehdr_start to point to our own ELF header if it is visible in a +- segment that also includes the phdrs. If that's not available, we use +- the old method that assumes the beginning of the file is part of the +- lowest-addressed PT_LOAD segment. */ +- +- /* Set up the program header information for the dynamic linker +- itself. It is needed in the dl_iterate_phdr callbacks. */ +- const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start; +- assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); +- assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); +- +- const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff; +- +- GL(dl_rtld_map).l_phdr = rtld_phdr; +- GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; +- +- +- /* PT_GNU_RELRO is usually the last phdr. */ +- size_t cnt = rtld_ehdr->e_phnum; +- while (cnt-- > 0) +- if (rtld_phdr[cnt].p_type == PT_GNU_RELRO) +- { +- GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr; +- GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz; +- break; +- } ++ rtld_setup_phdr (); + + /* Add the dynamic linker to the TLS list if it also uses TLS. */ + if (GL(dl_rtld_map).l_tls_blocksize != 0) +-- +2.27.0 + diff --git a/elf-Handle-ld.so-with-LOAD-segment-gaps-in-_dl_find_.patch b/elf-Handle-ld.so-with-LOAD-segment-gaps-in-_dl_find_.patch new file mode 100644 index 0000000..74c3c78 --- /dev/null +++ b/elf-Handle-ld.so-with-LOAD-segment-gaps-in-_dl_find_.patch @@ -0,0 +1,476 @@ +From 1bdce2545588a837f4b6715a90f5a22f9fc99c46 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Fri, 1 Aug 2025 12:19:49 +0200 +Subject: [PATCH] elf: Handle ld.so with LOAD segment gaps in + _dl_find_object (bug 31943) + +Detect if ld.so not contiguous and handle that case in _dl_find_object. +Set l_find_object_processed even for initially loaded link maps, +otherwise dlopen of an initially loaded object adds it to +_dlfo_loaded_mappings (where maps are expected to be contiguous), +in addition to _dlfo_nodelete_mappings. + +Test elf/tst-link-map-contiguous-ldso iterates over the loader +image, reading every word to make sure memory is actually mapped. +It only does that if the l_contiguous flag is set for the link map. +Otherwise, it finds gaps with mmap and checks that _dl_find_object +does not return the ld.so mapping for them. + +The test elf/tst-link-map-contiguous-main does the same thing for +the libc.so shared object. This only works if the kernel loaded +the main program because the glibc dynamic loader may fill +the gaps with PROT_NONE mappings in some cases, making it contiguous, +but accesses to individual words may still fault. + +Test elf/tst-link-map-contiguous-libc is again slightly different +because the dynamic loader always fills the gaps with PROT_NONE +mappings, so a different form of probing has to be used. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 20681be149b9eb1b6c1f4246bf4bd801221c86cd) +--- + NEWS | 1 + + elf/Makefile | 6 ++ + elf/dl-find_object.c | 78 +++++++++++++++--------- + elf/dl-find_object.h | 4 +- + elf/rtld.c | 25 +++++++- + elf/tst-link-map-contiguous-ldso.c | 98 ++++++++++++++++++++++++++++++ + elf/tst-link-map-contiguous-libc.c | 57 +++++++++++++++++ + elf/tst-link-map-contiguous-main.c | 45 ++++++++++++++ + 8 files changed, 283 insertions(+), 31 deletions(-) + create mode 100644 elf/tst-link-map-contiguous-ldso.c + create mode 100644 elf/tst-link-map-contiguous-libc.c + create mode 100644 elf/tst-link-map-contiguous-main.c + +diff --git a/NEWS b/NEWS +index cbc15745f5..41c48e1997 100644 +--- a/NEWS ++++ b/NEWS +@@ -60,6 +60,7 @@ The following bugs are resolved with this release: + [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic + [31476] resolv: Track single-request fallback via _res._flags + [31890] resolv: Allow short error responses to match any DNS query ++ [31943] _dl_find_object can fail if ld.so contains gaps between load segments + [31965] rseq extension mechanism does not work as intended + [31968] mremap implementation in C does not handle arguments correctly + [32052] Name space violation in fortify wrappers +diff --git a/elf/Makefile b/elf/Makefile +index ff14e80900..098d9a15b7 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -497,6 +497,8 @@ tests-internal += \ + tst-dl_find_object \ + tst-dl_find_object-threads \ + tst-dlmopen2 \ ++ tst-link-map-contiguous-ldso \ ++ tst-link-map-contiguous-libc \ + tst-ptrguard1 \ + tst-stackguard1 \ + tst-tls-surplus \ +@@ -508,6 +510,10 @@ tests-internal += \ + unload2 \ + # tests-internal + ++ifeq ($(build-hardcoded-path-in-tests),yes) ++tests-internal += tst-link-map-contiguous-main ++endif ++ + tests-container += \ + tst-dlopen-self-container \ + tst-dlopen-tlsmodid-container \ +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index c1390ee10f..d750d58bfa 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -465,6 +465,37 @@ _dl_find_object (void *pc1, struct dl_find_object *result) + } + rtld_hidden_def (_dl_find_object) + ++/* Subroutine of _dlfo_process_initial to split out noncontigous link ++ maps. NODELETE is the number of used _dlfo_nodelete_mappings ++ elements. It is incremented as needed, and the new NODELETE value ++ is returned. */ ++static size_t ++_dlfo_process_initial_noncontiguous_map (struct link_map *map, ++ size_t nodelete) ++{ ++ struct dl_find_object_internal dlfo; ++ _dl_find_object_from_map (map, &dlfo); ++ ++ /* PT_LOAD segments for a non-contiguous link map are added to the ++ non-closeable mappings. */ ++ const ElfW(Phdr) *ph = map->l_phdr; ++ const ElfW(Phdr) *ph_end = map->l_phdr + map->l_phnum; ++ for (; ph < ph_end; ++ph) ++ if (ph->p_type == PT_LOAD) ++ { ++ if (_dlfo_nodelete_mappings != NULL) ++ { ++ /* Second pass only. */ ++ _dlfo_nodelete_mappings[nodelete] = dlfo; ++ ElfW(Addr) start = ph->p_vaddr + map->l_addr; ++ _dlfo_nodelete_mappings[nodelete].map_start = start; ++ _dlfo_nodelete_mappings[nodelete].map_end = start + ph->p_memsz; ++ } ++ ++nodelete; ++ } ++ return nodelete; ++} ++ + /* _dlfo_process_initial is called twice. First to compute the array + sizes from the initial loaded mappings. Second to fill in the + bases and infos arrays with the (still unsorted) data. Returns the +@@ -476,29 +507,8 @@ _dlfo_process_initial (void) + + size_t nodelete = 0; + if (!main_map->l_contiguous) +- { +- struct dl_find_object_internal dlfo; +- _dl_find_object_from_map (main_map, &dlfo); +- +- /* PT_LOAD segments for a non-contiguous are added to the +- non-closeable mappings. */ +- for (const ElfW(Phdr) *ph = main_map->l_phdr, +- *ph_end = main_map->l_phdr + main_map->l_phnum; +- ph < ph_end; ++ph) +- if (ph->p_type == PT_LOAD) +- { +- if (_dlfo_nodelete_mappings != NULL) +- { +- /* Second pass only. */ +- _dlfo_nodelete_mappings[nodelete] = dlfo; +- _dlfo_nodelete_mappings[nodelete].map_start +- = ph->p_vaddr + main_map->l_addr; +- _dlfo_nodelete_mappings[nodelete].map_end +- = _dlfo_nodelete_mappings[nodelete].map_start + ph->p_memsz; +- } +- ++nodelete; +- } +- } ++ /* Contiguous case already handled in _dl_find_object_init. */ ++ nodelete = _dlfo_process_initial_noncontiguous_map (main_map, nodelete); + + size_t loaded = 0; + for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns) +@@ -510,11 +520,22 @@ _dlfo_process_initial (void) + /* lt_library link maps are implicitly NODELETE. */ + if (l->l_type == lt_library || l->l_nodelete_active) + { +- if (_dlfo_nodelete_mappings != NULL) +- /* Second pass only. */ +- _dl_find_object_from_map +- (l, _dlfo_nodelete_mappings + nodelete); +- ++nodelete; ++ /* The kernel may have loaded ld.so with gaps. */ ++ if (!l->l_contiguous ++#ifdef SHARED ++ && l == &GL(dl_rtld_map) ++#endif ++ ) ++ nodelete ++ = _dlfo_process_initial_noncontiguous_map (l, nodelete); ++ else ++ { ++ if (_dlfo_nodelete_mappings != NULL) ++ /* Second pass only. */ ++ _dl_find_object_from_map ++ (l, _dlfo_nodelete_mappings + nodelete); ++ ++nodelete; ++ } + } + else if (l->l_type == lt_loaded) + { +@@ -756,7 +777,6 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t count) + /* Prefer newly loaded link map. */ + assert (loaded_index1 > 0); + _dl_find_object_from_map (loaded[loaded_index1 - 1], dlfo); +- loaded[loaded_index1 - 1]->l_find_object_processed = 1; + --loaded_index1; + } + +diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h +index 87c9460619..b6ce6140be 100644 +--- a/elf/dl-find_object.h ++++ b/elf/dl-find_object.h +@@ -87,7 +87,7 @@ _dl_find_object_to_external (struct dl_find_object_internal *internal, + } + + /* Extract the object location data from a link map and writes it to +- *RESULT using relaxed MO stores. */ ++ *RESULT using relaxed MO stores. Set L->l_find_object_processed. */ + static void __attribute__ ((unused)) + _dl_find_object_from_map (struct link_map *l, + struct dl_find_object_internal *result) +@@ -100,6 +100,8 @@ _dl_find_object_from_map (struct link_map *l, + atomic_store_relaxed (&result->eh_dbase, (void *) l->l_info[DT_PLTGOT]); + #endif + ++ l->l_find_object_processed = 1; ++ + for (const ElfW(Phdr) *ph = l->l_phdr, *ph_end = l->l_phdr + l->l_phnum; + ph < ph_end; ++ph) + if (ph->p_type == DLFO_EH_SEGMENT_TYPE) +diff --git a/elf/rtld.c b/elf/rtld.c +index 8b7b0ff484..e1c7e7fcfb 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1292,7 +1292,7 @@ rtld_setup_main_map (struct link_map *main_map) + + /* Set up the program header information for the dynamic linker + itself. It can be accessed via _r_debug and dl_iterate_phdr +- callbacks. */ ++ callbacks, and it is used by _dl_find_object. */ + static void + rtld_setup_phdr (void) + { +@@ -1310,6 +1310,29 @@ rtld_setup_phdr (void) + GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; + + ++ GL(dl_rtld_map).l_contiguous = 1; ++ /* The linker may not have produced a contiguous object. The kernel ++ will load the object with actual gaps (unlike the glibc loader ++ for shared objects, which always produces a contiguous mapping). ++ See similar logic in rtld_setup_main_map above. */ ++ { ++ ElfW(Addr) expected_load_address = 0; ++ for (const ElfW(Phdr) *ph = rtld_phdr; ph < &rtld_phdr[rtld_ehdr->e_phnum]; ++ ++ph) ++ if (ph->p_type == PT_LOAD) ++ { ++ ElfW(Addr) mapstart = ph->p_vaddr & ~(GLRO(dl_pagesize) - 1); ++ if (GL(dl_rtld_map).l_contiguous && expected_load_address != 0 ++ && expected_load_address != mapstart) ++ GL(dl_rtld_map).l_contiguous = 0; ++ ElfW(Addr) allocend = ph->p_vaddr + ph->p_memsz; ++ /* The next expected address is the page following this load ++ segment. */ ++ expected_load_address = ((allocend + GLRO(dl_pagesize) - 1) ++ & ~(GLRO(dl_pagesize) - 1)); ++ } ++ } ++ + /* PT_GNU_RELRO is usually the last phdr. */ + size_t cnt = rtld_ehdr->e_phnum; + while (cnt-- > 0) +diff --git a/elf/tst-link-map-contiguous-ldso.c b/elf/tst-link-map-contiguous-ldso.c +new file mode 100644 +index 0000000000..04de808bb2 +--- /dev/null ++++ b/elf/tst-link-map-contiguous-ldso.c +@@ -0,0 +1,98 @@ ++/* Check that _dl_find_object behavior matches up with gaps. ++ Copyright (C) 2025 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 ++ ++static int ++do_test (void) ++{ ++ struct link_map *l = xdlopen (LD_SO, RTLD_NOW); ++ if (!l->l_contiguous) ++ { ++ puts ("info: ld.so link map is not contiguous"); ++ ++ /* Try to find holes by probing with mmap. */ ++ int pagesize = getpagesize (); ++ bool gap_found = false; ++ ElfW(Addr) addr = l->l_map_start; ++ TEST_COMPARE (addr % pagesize, 0); ++ while (addr < l->l_map_end) ++ { ++ void *expected = (void *) addr; ++ void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ struct dl_find_object dlfo; ++ int dlfo_ret = _dl_find_object (expected, &dlfo); ++ if (ptr == expected) ++ { ++ if (dlfo_ret < 0) ++ { ++ TEST_COMPARE (dlfo_ret, -1); ++ printf ("info: hole without mapping data found at %p\n", ptr); ++ } ++ else ++ FAIL ("object \"%s\" found in gap at %p", ++ dlfo.dlfo_link_map->l_name, ptr); ++ gap_found = true; ++ } ++ else if (dlfo_ret == 0) ++ { ++ if ((void *) dlfo.dlfo_link_map != (void *) l) ++ { ++ printf ("info: object \"%s\" found at %p\n", ++ dlfo.dlfo_link_map->l_name, ptr); ++ gap_found = true; ++ } ++ } ++ else ++ TEST_COMPARE (dlfo_ret, -1); ++ xmunmap (ptr, 1); ++ addr += pagesize; ++ } ++ if (!gap_found) ++ FAIL ("no ld.so gap found"); ++ } ++ else ++ { ++ puts ("info: ld.so link map is contiguous"); ++ ++ /* Assert that ld.so is truly contiguous in memory. */ ++ volatile long int *p = (volatile long int *) l->l_map_start; ++ volatile long int *end = (volatile long int *) l->l_map_end; ++ while (p < end) ++ { ++ *p; ++ ++p; ++ } ++ } ++ ++ xdlclose (l); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-link-map-contiguous-libc.c b/elf/tst-link-map-contiguous-libc.c +new file mode 100644 +index 0000000000..eb5728c765 +--- /dev/null ++++ b/elf/tst-link-map-contiguous-libc.c +@@ -0,0 +1,57 @@ ++/* Check that the entire libc.so program image is readable if contiguous. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct link_map *l = xdlopen (LIBC_SO, RTLD_NOW); ++ ++ /* The dynamic loader fills holes with PROT_NONE mappings. */ ++ if (!l->l_contiguous) ++ FAIL_EXIT1 ("libc.so link map is not contiguous"); ++ ++ /* Direct probing does not work because not everything is readable ++ due to PROT_NONE mappings. */ ++ int pagesize = getpagesize (); ++ ElfW(Addr) addr = l->l_map_start; ++ TEST_COMPARE (addr % pagesize, 0); ++ while (addr < l->l_map_end) ++ { ++ void *expected = (void *) addr; ++ void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ if (ptr == expected) ++ FAIL ("hole in libc.so memory image after %lu bytes", ++ (unsigned long int) (addr - l->l_map_start)); ++ xmunmap (ptr, 1); ++ addr += pagesize; ++ } ++ ++ xdlclose (l); ++ ++ return 0; ++} ++#include +diff --git a/elf/tst-link-map-contiguous-main.c b/elf/tst-link-map-contiguous-main.c +new file mode 100644 +index 0000000000..2d1a054f0f +--- /dev/null ++++ b/elf/tst-link-map-contiguous-main.c +@@ -0,0 +1,45 @@ ++/* Check that the entire main program image is readable if contiguous. ++ Copyright (C) 2025 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) ++{ ++ struct link_map *l = xdlopen ("", RTLD_NOW); ++ if (!l->l_contiguous) ++ FAIL_UNSUPPORTED ("main link map is not contiguous"); ++ ++ /* This check only works if the kernel loaded the main program. The ++ dynamic loader replaces gaps with PROT_NONE mappings, resulting ++ in faults. */ ++ volatile long int *p = (volatile long int *) l->l_map_start; ++ volatile long int *end = (volatile long int *) l->l_map_end; ++ while (p < end) ++ { ++ *p; ++ ++p; ++ } ++ ++ xdlclose (l); ++ ++ return 0; ++} ++#include +-- +2.27.0 + diff --git a/glibc.spec b/glibc.spec index b86e09b..49112c0 100644 --- a/glibc.spec +++ b/glibc.spec @@ -67,7 +67,7 @@ ############################################################################## Name: glibc Version: 2.38 -Release: 66 +Release: 67 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -308,6 +308,49 @@ Patch218: malloc-add-indirection-for-malloc-like-functions-in-.patch Patch219: malloc-obscure-calloc-use-in-tst-calloc.patch Patch220: malloc-cleanup-casts-in-tst-calloc.patch Patch221: posix-Fix-double-free-after-allocation-failure-in-re.patch +Patch222: arm-Use-_dl_find_object-on-__gnu_Unwind_Find_exidx-B.patch +Patch223: elf-Do-not-add-a-copy-of-_dl_find_object-to-libc.so.patch +Patch224: elf-Extract-rtld_setup_phdr-function-from-dl_main.patch +Patch225: elf-Handle-ld.so-with-LOAD-segment-gaps-in-_dl_find_.patch +Patch226: x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-BZ-33212.patch +Patch227: i386-Remove-CET-support.patch +Patch228: x86-64-Save-APX-registers-in-ld.so-trampoline.patch +Patch229: debug-Adapt-fortify-tests-to-libsupport.patch +Patch230: debug-Wire-up-tst-longjmp_chk3.patch +Patch231: debug-Fix-tst-longjmp_chk3-build-failure-on-Hurd.patch +Patch232: Remove-installed-header-rule-on-.-include-.h.patch +Patch233: Update-syscall-lists-for-Linux-6.6.patch +Patch234: Update-syscall-lists-for-Linux-6.7.patch +Patch235: x86-cet-Check-user_shstk-in-proc-cpuinfo.patch +Patch236: x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch +Patch237: x86-cet-Check-legacy-shadow-stack-applications.patch +Patch238: x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disable.patch +Patch239: x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hwcap.patch +Patch240: x86-cet-Check-legacy-shadow-stack-code-in-.init_arra.patch +Patch241: x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mode.patch +Patch242: x86-cet-Update-tst-cet-vfork-1.patch +Patch243: x86-Modularize-sysdeps-x86-dl-cet.c.patch +Patch244: x86-cet-Don-t-disable-CET-if-not-single-threaded.patch +Patch245: x86-cet-Sync-with-Linux-kernel-6.6-shadow-stack-inte.patch +Patch246: x86-cet-Enable-shadow-stack-during-startup.patch +Patch247: x86-cet-Check-feature_1-in-TCB-for-active-IBT-and-SH.patch +Patch248: x86-cet-Don-t-set-CET-active-by-default.patch +Patch249: x86-cet-Run-some-CET-tests-with-shadow-stack.patch +Patch250: x86-cet-Add-fcf-protection-none-before-fcf-protectio.patch +Patch251: i386-Ignore-enable-cet.patch +Patch252: x86-64-cet-Check-the-restore-token-in-longjmp.patch +Patch253: i386-Fail-if-configured-with-enable-cet.patch +Patch254: x86-64-cet-Move-dl-cet.-ch-to-x86_64-directories.patch +Patch255: x86-Move-CET-infrastructure-to-x86_64.patch +Patch256: x86-64-cet-Move-check-cet.awk-to-x86_64.patch +Patch257: i386-Remove-CET-support-bits.patch +Patch258: x86-64-cet-Make-CET-feature-check-specific-to-Linux-.patch +Patch259: x86-cet-fix-shadow-stack-test-scripts.patch +Patch260: x86-64-Remove-sysdeps-x86_64-x32-dl-machine.h.patch +Patch261: x32-cet-Support-shadow-stack-during-startup-for-Linu.patch +Patch262: x86-Update-_dl_tlsdesc_dynamic-to-preserve-caller-sa.patch +Patch263: x86-64-Update-_dl_tlsdesc_dynamic-to-preserve-AMX-re.patch +Patch264: x86-64-Allocate-state-buffer-space-for-RDI-RSI-and-R.patch #openEuler patch list Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch @@ -1536,6 +1579,9 @@ fi %endif %changelog +* Wed Aug 20 2025 Qingqing Li - 2.38-67 +- sync from glibc upstream 2.38 branch + * Wed Jul 30 2025 Qingqing Li - 2.38-66 - posix: Fix double-free after allocation failure in regcomp (bug 33185 CVE-2025-8058) diff --git a/i386-Fail-if-configured-with-enable-cet.patch b/i386-Fail-if-configured-with-enable-cet.patch new file mode 100644 index 0000000..dfcbcc5 --- /dev/null +++ b/i386-Fail-if-configured-with-enable-cet.patch @@ -0,0 +1,101 @@ +From 16c478bc2891c739951b4811b06ec6c29afd6c49 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 5 Jan 2024 10:41:03 -0300 +Subject: [PATCH] i386: Fail if configured with --enable-cet + +Since it is only supported for x86_64. + +Checked on i686-linux-gnu. + +(cherry picked from commit a0cfc48e8a67506e3f0b2d3ea5e04b45408b3683) +--- + INSTALL | 3 +-- + NEWS | 4 ++-- + manual/install.texi | 3 +-- + sysdeps/i386/configure | 8 ++++---- + sysdeps/i386/configure.ac | 7 ++++--- + 5 files changed, 12 insertions(+), 13 deletions(-) + +diff --git a/INSTALL b/INSTALL +index d583ca7b44..4365d909a2 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -147,8 +147,7 @@ if ‘CFLAGS’ is specified it must enable optimization. For example: + ‘--enable-cet=permissive’, CET is disabled when dlopening a non CET + enabled shared library in CET enabled application. + +- NOTE: ‘--enable-cet’ has been tested for x86_64 and x32 on non-CET +- and CET processors. ++ NOTE: ‘--enable-cet’ is only supported on x86_64 and x32. + + ‘--enable-memory-tagging’ + Enable memory tagging support if the architecture supports it. +diff --git a/NEWS b/NEWS +index 65b5903622..77e89c9619 100644 +--- a/NEWS ++++ b/NEWS +@@ -7,8 +7,8 @@ using `glibc' in the "product" field. + + Version 2.38.1 + +-* Sync with Linux kernel 6.6 shadow stack interface. Since only x86-64 +- is supported, --enable-cet is ignored for i386. ++* Sync with Linux kernel 6.6 shadow stack interface. The --enable-cet ++ configure option in only supported on x86-64. + + Deprecated and removed features, and other changes affecting compatibility: + +diff --git a/manual/install.texi b/manual/install.texi +index 2af7f35c4e..479a49c7dc 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -175,8 +175,7 @@ enabled shared library in CET enabled application. With + @option{--enable-cet=permissive}, CET is disabled when dlopening a + non CET enabled shared library in CET enabled application. + +-NOTE: @option{--enable-cet} has been tested for x86_64 and x32 +-on non-CET and CET processors. ++NOTE: @option{--enable-cet} is only supported on x86_64 and x32. + + @item --enable-memory-tagging + Enable memory tagging support if the architecture supports it. When +diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure +index cd63d314fa..84656cef6e 100644 +--- a/sysdeps/i386/configure ++++ b/sysdeps/i386/configure +@@ -1,10 +1,10 @@ + # This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/i386. + +-# CET is only supported for x86-64. Set enable-cet to "no" to allow +-# "ifneq ($(enable-cet),no)" in x86 Makefiles. +-config_vars="$config_vars +-enable-cet = "no"" ++# CET is only supported for x86-64. ++if test $enable_cet != no; then ++ as_fn_error $? "\"CET is only supported on x86_64 or x32\"" "$LINENO" 5 ++fi + + # We no longer support i386 since it lacks the atomic instructions + # required to implement NPTL threading. +diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac +index b7d9436557..7f68e6210a 100644 +--- a/sysdeps/i386/configure.ac ++++ b/sysdeps/i386/configure.ac +@@ -1,9 +1,10 @@ + GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # Local configure fragment for sysdeps/i386. + +-# CET is only supported for x86-64. Set enable-cet to "no" to allow +-# "ifneq ($(enable-cet),no)" in x86 Makefiles. +-LIBC_CONFIG_VAR([enable-cet], ["no"]) ++# CET is only supported for x86-64. ++if test $enable_cet != no; then ++ AC_MSG_ERROR(["CET is only supported on x86_64 or x32"]) ++fi + + # We no longer support i386 since it lacks the atomic instructions + # required to implement NPTL threading. +-- +2.27.0 + diff --git a/i386-Ignore-enable-cet.patch b/i386-Ignore-enable-cet.patch new file mode 100644 index 0000000..ad5fef9 --- /dev/null +++ b/i386-Ignore-enable-cet.patch @@ -0,0 +1,403 @@ +From 9800c19dde5c5dfc18c643fb62a2f5bd64800df0 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 3 Jan 2024 12:09:23 -0800 +Subject: [PATCH] i386: Ignore --enable-cet + +Since shadow stack is only supported for x86-64, ignore --enable-cet for +i386. Always setting $(enable-cet) for i386 to "no" to support + +ifneq ($(enable-cet),no) + +in x86 Makefiles. We can't use + +ifeq ($(enable-cet),yes) + +since $(enable-cet) can be "yes", "no" or "permissive". +Reviewed-by: Adhemerval Zanella + +(cherry picked from commit bbfb54930cdd85269504a34b362e77a3ac2a207a) +--- + INSTALL | 19 +++++----- + NEWS | 3 ++ + manual/install.texi | 11 +++--- + sysdeps/i386/configure | 5 +++ + sysdeps/i386/configure.ac | 4 +++ + sysdeps/x86/configure | 70 ------------------------------------- + sysdeps/x86/configure.ac | 43 ----------------------- + sysdeps/x86_64/configure | 70 +++++++++++++++++++++++++++++++++++++ + sysdeps/x86_64/configure.ac | 43 +++++++++++++++++++++++ + 9 files changed, 137 insertions(+), 131 deletions(-) + +diff --git a/INSTALL b/INSTALL +index 268acadd75..d583ca7b44 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -141,17 +141,14 @@ if ‘CFLAGS’ is specified it must enable optimization. For example: + indirect branch tracking (IBT) and shadow stack (SHSTK). When CET + is enabled, the GNU C Library is compatible with all existing + executables and shared libraries. This feature is currently +- supported on i386, x86_64 and x32 with GCC 8 and binutils 2.29 or +- later. Note that when CET is enabled, the GNU C Library requires +- CPUs capable of multi-byte NOPs, like x86-64 processors as well as +- Intel Pentium Pro or newer. With ‘--enable-cet’, it is an error to +- dlopen a non CET enabled shared library in CET enabled application. +- With ‘--enable-cet=permissive’, CET is disabled when dlopening a +- non CET enabled shared library in CET enabled application. +- +- NOTE: ‘--enable-cet’ has been tested for i686, x86_64 and x32 on +- non-CET processors. ‘--enable-cet’ has been tested for i686, +- x86_64 and x32 on CET processors. ++ supported on x86_64 and x32 with GCC 8 and binutils 2.29 or later. ++ With ‘--enable-cet’, it is an error to dlopen a non CET enabled ++ shared library in CET enabled application. With ++ ‘--enable-cet=permissive’, CET is disabled when dlopening a non CET ++ enabled shared library in CET enabled application. ++ ++ NOTE: ‘--enable-cet’ has been tested for x86_64 and x32 on non-CET ++ and CET processors. + + ‘--enable-memory-tagging’ + Enable memory tagging support if the architecture supports it. +diff --git a/NEWS b/NEWS +index 41c48e1997..65b5903622 100644 +--- a/NEWS ++++ b/NEWS +@@ -7,6 +7,9 @@ using `glibc' in the "product" field. + + Version 2.38.1 + ++* Sync with Linux kernel 6.6 shadow stack interface. Since only x86-64 ++ is supported, --enable-cet is ignored for i386. ++ + Deprecated and removed features, and other changes affecting compatibility: + + * __rseq_size now denotes the size of the active rseq area (20 bytes +diff --git a/manual/install.texi b/manual/install.texi +index e8f36d5726..2af7f35c4e 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -169,17 +169,14 @@ Enable Intel Control-flow Enforcement Technology (CET) support. When + is protected with indirect branch tracking (IBT) and shadow stack + (SHSTK)@. When CET is enabled, @theglibc{} is compatible with all + existing executables and shared libraries. This feature is currently +-supported on i386, x86_64 and x32 with GCC 8 and binutils 2.29 or later. +-Note that when CET is enabled, @theglibc{} requires CPUs capable of +-multi-byte NOPs, like x86-64 processors as well as Intel Pentium Pro or +-newer. With @option{--enable-cet}, it is an error to dlopen a non CET ++supported on x86_64 and x32 with GCC 8 and binutils 2.29 or later. ++With @option{--enable-cet}, it is an error to dlopen a non CET + enabled shared library in CET enabled application. With + @option{--enable-cet=permissive}, CET is disabled when dlopening a + non CET enabled shared library in CET enabled application. + +-NOTE: @option{--enable-cet} has been tested for i686, x86_64 and x32 +-on non-CET processors. @option{--enable-cet} has been tested for +-i686, x86_64 and x32 on CET processors. ++NOTE: @option{--enable-cet} has been tested for x86_64 and x32 ++on non-CET and CET processors. + + @item --enable-memory-tagging + Enable memory tagging support if the architecture supports it. When +diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure +index f5c3a281ac..cd63d314fa 100644 +--- a/sysdeps/i386/configure ++++ b/sysdeps/i386/configure +@@ -1,6 +1,11 @@ + # This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/i386. + ++# CET is only supported for x86-64. Set enable-cet to "no" to allow ++# "ifneq ($(enable-cet),no)" in x86 Makefiles. ++config_vars="$config_vars ++enable-cet = "no"" ++ + # We no longer support i386 since it lacks the atomic instructions + # required to implement NPTL threading. + if test "$config_machine" = i386; then +diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac +index 234ef2454a..b7d9436557 100644 +--- a/sysdeps/i386/configure.ac ++++ b/sysdeps/i386/configure.ac +@@ -1,6 +1,10 @@ + GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # Local configure fragment for sysdeps/i386. + ++# CET is only supported for x86-64. Set enable-cet to "no" to allow ++# "ifneq ($(enable-cet),no)" in x86 Makefiles. ++LIBC_CONFIG_VAR([enable-cet], ["no"]) ++ + # We no longer support i386 since it lacks the atomic instructions + # required to implement NPTL threading. + if test "$config_machine" = i386; then +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index a2f9a7c2c6..1f4c2d67fd 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -1,76 +1,6 @@ + # This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/x86. + +-if test $enable_cet != no; then +- # Check if CET can be enabled. +- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether CET can be enabled" >&5 +-printf %s "checking whether CET can be enabled... " >&6; } +-if test ${libc_cv_x86_cet_available+y} +-then : +- printf %s "(cached) " >&6 +-else $as_nop +- cat > conftest.c <&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then +- libc_cv_x86_cet_available=yes +- else +- libc_cv_x86_cet_available=no +- fi +- rm -rf conftest* +-fi +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_available" >&5 +-printf "%s\n" "$libc_cv_x86_cet_available" >&6; } +- if test $libc_cv_x86_cet_available != yes; then +- as_fn_error $? "$CC doesn't support CET" "$LINENO" 5 +- fi +-fi +-if test $enable_cet != no; then +- # Check if assembler supports CET. +- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether assembler supports CET" >&5 +-printf %s "checking whether assembler supports CET... " >&6; } +-if test ${libc_cv_x86_cet_as+y} +-then : +- printf %s "(cached) " >&6 +-else $as_nop +- cat > conftest.s <&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then +- libc_cv_x86_cet_as=yes +- else +- libc_cv_x86_cet_as=no +- fi +- rm -rf conftest* +-fi +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_as" >&5 +-printf "%s\n" "$libc_cv_x86_cet_as" >&6; } +- if test $libc_cv_x86_cet_as = no; then +- as_fn_error $? "$AS doesn't support CET" "$LINENO" 5 +- fi +-fi +-if test $enable_cet = yes; then +- printf "%s\n" "#define DEFAULT_DL_X86_CET_CONTROL cet_elf_property" >>confdefs.h +- +-elif test $enable_cet = permissive; then +- printf "%s\n" "#define DEFAULT_DL_X86_CET_CONTROL cet_permissive" >>confdefs.h +- +-fi +-config_vars="$config_vars +-enable-cet = $enable_cet" +- + # Check if linker supports x86 ISA level. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker x86 ISA level support" >&5 + printf %s "checking for linker x86 ISA level support... " >&6; } +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index c854bc74ca..437a50623b 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -1,49 +1,6 @@ + GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + # Local configure fragment for sysdeps/x86. + +-if test $enable_cet != no; then +- # Check if CET can be enabled. +- AC_CACHE_CHECK(whether CET can be enabled, +- libc_cv_x86_cet_available, [dnl +-cat > conftest.c <&AS_MESSAGE_LOG_FD); then +- libc_cv_x86_cet_available=yes +- else +- libc_cv_x86_cet_available=no +- fi +- rm -rf conftest*]) +- if test $libc_cv_x86_cet_available != yes; then +- AC_MSG_ERROR([$CC doesn't support CET]) +- fi +-fi +-if test $enable_cet != no; then +- # Check if assembler supports CET. +- AC_CACHE_CHECK(whether assembler supports CET, +- libc_cv_x86_cet_as, [dnl +-cat > conftest.s <&AS_MESSAGE_LOG_FD); then +- libc_cv_x86_cet_as=yes +- else +- libc_cv_x86_cet_as=no +- fi +- rm -rf conftest*]) +- if test $libc_cv_x86_cet_as = no; then +- AC_MSG_ERROR([$AS doesn't support CET]) +- fi +-fi +-if test $enable_cet = yes; then +- AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_elf_property) +-elif test $enable_cet = permissive; then +- AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_permissive) +-fi +-LIBC_CONFIG_VAR([enable-cet], [$enable_cet]) +- + # Check if linker supports x86 ISA level. + AC_CACHE_CHECK([for linker x86 ISA level support], + libc_cv_include_x86_isa_level, [dnl +diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure +index e307467afa..b4a80b8035 100755 +--- a/sysdeps/x86_64/configure ++++ b/sysdeps/x86_64/configure +@@ -29,6 +29,76 @@ if test x"$build_mathvec" = xnotset; then + build_mathvec=yes + fi + ++if test $enable_cet != no; then ++ # Check if CET can be enabled. ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether CET can be enabled" >&5 ++printf %s "checking whether CET can be enabled... " >&6; } ++if test ${libc_cv_x86_cet_available+y} ++then : ++ printf %s "(cached) " >&6 ++else $as_nop ++ cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ libc_cv_x86_cet_available=yes ++ else ++ libc_cv_x86_cet_available=no ++ fi ++ rm -rf conftest* ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_available" >&5 ++printf "%s\n" "$libc_cv_x86_cet_available" >&6; } ++ if test $libc_cv_x86_cet_available != yes; then ++ as_fn_error $? "$CC doesn't support CET" "$LINENO" 5 ++ fi ++fi ++if test $enable_cet != no; then ++ # Check if assembler supports CET. ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether assembler supports CET" >&5 ++printf %s "checking whether assembler supports CET... " >&6; } ++if test ${libc_cv_x86_cet_as+y} ++then : ++ printf %s "(cached) " >&6 ++else $as_nop ++ cat > conftest.s <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ libc_cv_x86_cet_as=yes ++ else ++ libc_cv_x86_cet_as=no ++ fi ++ rm -rf conftest* ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_as" >&5 ++printf "%s\n" "$libc_cv_x86_cet_as" >&6; } ++ if test $libc_cv_x86_cet_as = no; then ++ as_fn_error $? "$AS doesn't support CET" "$LINENO" 5 ++ fi ++fi ++if test $enable_cet = yes; then ++ printf "%s\n" "#define DEFAULT_DL_X86_CET_CONTROL cet_elf_property" >>confdefs.h ++ ++elif test $enable_cet = permissive; then ++ printf "%s\n" "#define DEFAULT_DL_X86_CET_CONTROL cet_permissive" >>confdefs.h ++ ++fi ++config_vars="$config_vars ++enable-cet = $enable_cet" ++ + test -n "$critic_missing" && as_fn_error $? " + *** $critic_missing" "$LINENO" 5 + +diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac +index 1215dcb1e4..937d1aff7e 100644 +--- a/sysdeps/x86_64/configure.ac ++++ b/sysdeps/x86_64/configure.ac +@@ -14,5 +14,48 @@ if test x"$build_mathvec" = xnotset; then + build_mathvec=yes + fi + ++if test $enable_cet != no; then ++ # Check if CET can be enabled. ++ AC_CACHE_CHECK(whether CET can be enabled, ++ libc_cv_x86_cet_available, [dnl ++cat > conftest.c <&AS_MESSAGE_LOG_FD); then ++ libc_cv_x86_cet_available=yes ++ else ++ libc_cv_x86_cet_available=no ++ fi ++ rm -rf conftest*]) ++ if test $libc_cv_x86_cet_available != yes; then ++ AC_MSG_ERROR([$CC doesn't support CET]) ++ fi ++fi ++if test $enable_cet != no; then ++ # Check if assembler supports CET. ++ AC_CACHE_CHECK(whether assembler supports CET, ++ libc_cv_x86_cet_as, [dnl ++cat > conftest.s <&AS_MESSAGE_LOG_FD); then ++ libc_cv_x86_cet_as=yes ++ else ++ libc_cv_x86_cet_as=no ++ fi ++ rm -rf conftest*]) ++ if test $libc_cv_x86_cet_as = no; then ++ AC_MSG_ERROR([$AS doesn't support CET]) ++ fi ++fi ++if test $enable_cet = yes; then ++ AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_elf_property) ++elif test $enable_cet = permissive; then ++ AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_permissive) ++fi ++LIBC_CONFIG_VAR([enable-cet], [$enable_cet]) ++ + test -n "$critic_missing" && AC_MSG_ERROR([ + *** $critic_missing]) +-- +2.27.0 + diff --git a/i386-Remove-CET-support-bits.patch b/i386-Remove-CET-support-bits.patch new file mode 100644 index 0000000..1b33158 --- /dev/null +++ b/i386-Remove-CET-support-bits.patch @@ -0,0 +1,304 @@ +From 0ca425964e45935240a6cf2822aa5ec61ede98bc Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 9 Jan 2024 12:23:27 -0800 +Subject: [PATCH] i386: Remove CET support bits + +1. Remove _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk. +2. Move CET offsets from x86 cpu-features-offsets.sym to x86-64 +features-offsets.sym. +3. Rename x86 cet-control.h to x86-64 feature-control.h since it is only +for x86-64 and also used for PLT rewrite. +4. Add x86-64 ldsodefs.h to include feature-control.h. +5. Change TUNABLE_CALLBACK (set_plt_rewrite) to x86-64 only. +6. Move x86 dl-procruntime.c to x86-64. +Reviewed-by: Adhemerval Zanella + +(cherry picked from commit 874214db624a8e6c5d2dbe47419fab126f330d68) +--- + sysdeps/i386/dl-machine.h | 11 +-- + sysdeps/i386/dl-trampoline.S | 69 ------------------- + sysdeps/unix/sysv/linux/x86_64/dl-cet.h | 2 +- + sysdeps/x86/cpu-features-offsets.sym | 2 - + sysdeps/x86/ldsodefs.h | 1 - + sysdeps/x86_64/Makefile | 2 +- + sysdeps/{x86 => x86_64}/dl-procruntime.c | 4 +- + sysdeps/x86_64/dl-trampoline.S | 1 + + .../feature-control.h} | 8 +-- + sysdeps/x86_64/features-offsets.sym | 6 ++ + sysdeps/x86_64/ldsodefs.h | 26 +++++++ + 11 files changed, 43 insertions(+), 89 deletions(-) + rename sysdeps/{x86 => x86_64}/dl-procruntime.c (94%) + rename sysdeps/{x86/cet-control.h => x86_64/feature-control.h} (90%) + create mode 100644 sysdeps/x86_64/features-offsets.sym + create mode 100644 sysdeps/x86_64/ldsodefs.h + +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index 18749f2ec2..b21322adc8 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -65,9 +65,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; + extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; +- /* Check if SHSTK is enabled by kernel. */ +- bool shstk_enabled +- = (GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0; + + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -94,9 +91,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + end in this function. */ + if (__glibc_unlikely (profile)) + { +- got[2] = (shstk_enabled +- ? (Elf32_Addr) &_dl_runtime_profile_shstk +- : (Elf32_Addr) &_dl_runtime_profile); ++ got[2] = (Elf32_Addr) &_dl_runtime_profile; + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) +@@ -107,9 +102,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + else + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ +- got[2] = (shstk_enabled +- ? (Elf32_Addr) &_dl_runtime_resolve_shstk +- : (Elf32_Addr) &_dl_runtime_resolve); ++ got[2] = (Elf32_Addr) &_dl_runtime_resolve; + } + + return lazy; +diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S +index 1c569290a5..5fe8600783 100644 +--- a/sysdeps/i386/dl-trampoline.S ++++ b/sysdeps/i386/dl-trampoline.S +@@ -44,76 +44,7 @@ _dl_runtime_resolve: + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + +-# The SHSTK compatible version. +- .text +- .globl _dl_runtime_resolve_shstk +- .type _dl_runtime_resolve_shstk, @function +- cfi_startproc +- .align 16 +-_dl_runtime_resolve_shstk: +- cfi_adjust_cfa_offset (8) +- pushl %eax # Preserve registers otherwise clobbered. +- cfi_adjust_cfa_offset (4) +- pushl %edx +- cfi_adjust_cfa_offset (4) +- movl 12(%esp), %edx # Copy args pushed by PLT in register. Note +- movl 8(%esp), %eax # that `fixup' takes its parameters in regs. +- call _dl_fixup # Call resolver. +- movl (%esp), %edx # Get register content back. +- movl %eax, %ecx # Store the function address. +- movl 4(%esp), %eax # Get register content back. +- addl $16, %esp # Adjust stack: PLT1 + PLT2 + %eax + %edx +- cfi_adjust_cfa_offset (-16) +- jmp *%ecx # Jump to function address. +- cfi_endproc +- .size _dl_runtime_resolve_shstk, .-_dl_runtime_resolve_shstk +- + #ifndef PROF +-# The SHSTK compatible version. +- .globl _dl_runtime_profile_shstk +- .type _dl_runtime_profile_shstk, @function +- cfi_startproc +- .align 16 +-_dl_runtime_profile_shstk: +- cfi_adjust_cfa_offset (8) +- pushl %esp +- cfi_adjust_cfa_offset (4) +- addl $8, (%esp) # Account for the pushed PLT data +- pushl %ebp +- cfi_adjust_cfa_offset (4) +- pushl %eax # Preserve registers otherwise clobbered. +- cfi_adjust_cfa_offset (4) +- pushl %ecx +- cfi_adjust_cfa_offset (4) +- pushl %edx +- cfi_adjust_cfa_offset (4) +- movl %esp, %ecx +- subl $8, %esp +- cfi_adjust_cfa_offset (8) +- movl $-1, 4(%esp) +- leal 4(%esp), %edx +- movl %edx, (%esp) +- pushl %ecx # Address of the register structure +- cfi_adjust_cfa_offset (4) +- movl 40(%esp), %ecx # Load return address +- movl 36(%esp), %edx # Copy args pushed by PLT in register. Note +- movl 32(%esp), %eax # that `fixup' takes its parameters in regs. +- call _dl_profile_fixup # Call resolver. +- cfi_adjust_cfa_offset (-8) +- movl (%esp), %edx +- testl %edx, %edx +- jns 1f +- movl 4(%esp), %edx # Get register content back. +- movl %eax, %ecx # Store the function address. +- movl 12(%esp), %eax # Get register content back. +- # Adjust stack: PLT1 + PLT2 + %esp + %ebp + %eax + %ecx + %edx +- # + free. +- addl $32, %esp +- cfi_adjust_cfa_offset (-32) +- jmp *%ecx # Jump to function address. +- cfi_endproc +- .size _dl_runtime_profile_shstk, .-_dl_runtime_profile_shstk +- + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc +diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +index 64022a631a..ed4a81ea3d 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +@@ -17,7 +17,7 @@ + + #include + #include +-#include ++#include + + static __always_inline int + dl_cet_disable_cet (unsigned int cet_feature) +diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym +index 5429f60632..6a8fd29813 100644 +--- a/sysdeps/x86/cpu-features-offsets.sym ++++ b/sysdeps/x86/cpu-features-offsets.sym +@@ -2,6 +2,4 @@ + + #include + +-RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET offsetof (struct rtld_global_ro, _dl_x86_cpu_features) + XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size) +-RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET offsetof (struct rtld_global, _dl_x86_feature_1) +diff --git a/sysdeps/x86/ldsodefs.h b/sysdeps/x86/ldsodefs.h +index 7af12e515f..fda0376738 100644 +--- a/sysdeps/x86/ldsodefs.h ++++ b/sysdeps/x86/ldsodefs.h +@@ -61,7 +61,6 @@ struct La_x32_retval; + struct La_x86_64_retval *, \ + const char *) + +-#include + #include_next + + #endif +diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile +index 36be2f6d56..a3b0440aa7 100644 +--- a/sysdeps/x86_64/Makefile ++++ b/sysdeps/x86_64/Makefile +@@ -2,7 +2,7 @@ + long-double-fcts = yes + + ifeq ($(subdir),csu) +-gen-as-const-headers += link-defines.sym ++gen-as-const-headers += features-offsets.sym link-defines.sym + endif + + ifeq ($(subdir),gmon) +diff --git a/sysdeps/x86/dl-procruntime.c b/sysdeps/x86_64/dl-procruntime.c +similarity index 94% +rename from sysdeps/x86/dl-procruntime.c +rename to sysdeps/x86_64/dl-procruntime.c +index 2fb682ded3..8457441315 100644 +--- a/sysdeps/x86/dl-procruntime.c ++++ b/sysdeps/x86_64/dl-procruntime.c +@@ -1,5 +1,5 @@ +-/* Data for processor runtime information. x86 version. +- Copyright (C) 2018-2023 Free Software Foundation, Inc. ++/* Data for processor runtime information. x86-64 version. ++ Copyright (C) 2018-2024 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 +diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S +index a6b9a1826b..3c18500690 100644 +--- a/sysdeps/x86_64/dl-trampoline.S ++++ b/sysdeps/x86_64/dl-trampoline.S +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +diff --git a/sysdeps/x86/cet-control.h b/sysdeps/x86_64/feature-control.h +similarity index 90% +rename from sysdeps/x86/cet-control.h +rename to sysdeps/x86_64/feature-control.h +index 3bd00019e8..d334804b19 100644 +--- a/sysdeps/x86/cet-control.h ++++ b/sysdeps/x86_64/feature-control.h +@@ -1,4 +1,4 @@ +-/* x86 CET tuning. ++/* x86-64 feature tuning. + This file is part of the GNU C Library. + Copyright (C) 2018-2023 Free Software Foundation, Inc. + +@@ -16,8 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef _CET_CONTROL_H +-#define _CET_CONTROL_H ++#ifndef _X86_64_FEATURE_CONTROL_H ++#define _X86_64_FEATURE_CONTROL_H + + /* For each CET feature, IBT and SHSTK, valid control values. */ + enum dl_x86_cet_control +@@ -38,4 +38,4 @@ struct dl_x86_feature_control + enum dl_x86_cet_control shstk : 2; + }; + +-#endif /* cet-control.h */ ++#endif /* feature-control.h */ +diff --git a/sysdeps/x86_64/features-offsets.sym b/sysdeps/x86_64/features-offsets.sym +new file mode 100644 +index 0000000000..9e4be3393a +--- /dev/null ++++ b/sysdeps/x86_64/features-offsets.sym +@@ -0,0 +1,6 @@ ++#define SHARED 1 ++ ++#include ++ ++RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET offsetof (struct rtld_global_ro, _dl_x86_cpu_features) ++RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET offsetof (struct rtld_global, _dl_x86_feature_1) +diff --git a/sysdeps/x86_64/ldsodefs.h b/sysdeps/x86_64/ldsodefs.h +new file mode 100644 +index 0000000000..0f468ddf5b +--- /dev/null ++++ b/sysdeps/x86_64/ldsodefs.h +@@ -0,0 +1,26 @@ ++/* Run-time dynamic linker data structures for loaded ELF shared objects. ++ x86-64 version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _X86_64_LDSODEFS_H ++#define _X86_64_LDSODEFS_H 1 ++ ++#include ++#include_next ++ ++#endif +-- +2.27.0 + diff --git a/i386-Remove-CET-support.patch b/i386-Remove-CET-support.patch new file mode 100644 index 0000000..da721fd --- /dev/null +++ b/i386-Remove-CET-support.patch @@ -0,0 +1,1638 @@ +From 768103fa49b752dd2d813335733c3d424df0cf62 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 5 Jan 2024 10:36:40 -0300 +Subject: [PATCH] i386: Remove CET support + +CET is only support for x86_64, this patch reverts: + + - faaee1f07ed x86: Support shadow stack pointer in setjmp/longjmp. + - be9ccd27c09 i386: Add _CET_ENDBR to indirect jump targets in + add_n.S/sub_n.S + - c02695d7764 x86/CET: Update vfork to prevent child return + - 5d844e1b725 i386: Enable CET support in ucontext functions + - 124bcde683 x86: Add _CET_ENDBR to functions in crti.S + - 562837c002 x86: Add _CET_ENDBR to functions in dl-tlsdesc.S + - f753fa7dea x86: Support IBT and SHSTK in Intel CET [BZ #21598] + - 825b58f3fb i386-mcount.S: Add _CET_ENDBR to _mcount and __fentry__ + - 7e119cd582 i386: Use _CET_NOTRACK in i686/memcmp.S + - 177824e232 i386: Use _CET_NOTRACK in memcmp-sse4.S + - 0a899af097 i386: Use _CET_NOTRACK in memcpy-ssse3-rep.S + - 7fb613361c i386: Use _CET_NOTRACK in memcpy-ssse3.S + - 77a8ae0948 i386: Use _CET_NOTRACK in memset-sse2-rep.S + - 00e7b76a8f i386: Use _CET_NOTRACK in memset-sse2.S + - 90d15dc577 i386: Use _CET_NOTRACK in strcat-sse2.S + - f1574581c7 i386: Use _CET_NOTRACK in strcpy-sse2.S + - 4031d7484a i386/sub_n.S: Add a missing _CET_ENDBR to indirect jump + - target + - +Checked on i686-linux-gnu. + +(cherry picked from commit 25f1e16ef03a6a8fb1701c4647d46c564480d88c) +--- + sysdeps/i386/__longjmp.S | 73 --------- + sysdeps/i386/add_n.S | 25 ---- + sysdeps/i386/bsd-_setjmp.S | 21 --- + sysdeps/i386/bsd-setjmp.S | 21 --- + sysdeps/i386/crti.S | 2 - + sysdeps/i386/dl-tlsdesc.S | 3 - + sysdeps/i386/dl-trampoline.S | 4 - + sysdeps/i386/i386-mcount.S | 2 - + sysdeps/i386/i686/add_n.S | 25 ---- + sysdeps/i386/i686/memcmp.S | 4 +- + sysdeps/i386/i686/multiarch/memcmp-sse4.S | 4 +- + .../i386/i686/multiarch/memcpy-ssse3-rep.S | 8 +- + sysdeps/i386/i686/multiarch/memcpy-ssse3.S | 4 +- + sysdeps/i386/i686/multiarch/memset-sse2-rep.S | 4 +- + sysdeps/i386/i686/multiarch/memset-sse2.S | 4 +- + sysdeps/i386/i686/multiarch/strcat-sse2.S | 4 +- + sysdeps/i386/i686/multiarch/strcpy-sse2.S | 4 +- + sysdeps/i386/setjmp.S | 21 --- + sysdeps/i386/start.S | 1 - + sysdeps/i386/sub_n.S | 25 ---- + sysdeps/i386/sysdep.h | 11 ++ + .../unix/sysv/linux/i386/____longjmp_chk.S | 37 ----- + sysdeps/unix/sysv/linux/i386/getcontext.S | 56 ------- + sysdeps/unix/sysv/linux/i386/makecontext.S | 123 ---------------- + sysdeps/unix/sysv/linux/i386/setcontext.S | 101 +------------ + sysdeps/unix/sysv/linux/i386/swapcontext.S | 139 ------------------ + sysdeps/unix/sysv/linux/i386/sysdep.h | 5 - + sysdeps/unix/sysv/linux/i386/ucontext_i.sym | 4 - + sysdeps/unix/sysv/linux/i386/vfork.S | 24 +-- + sysdeps/x86/sysdep.h | 44 ------ + sysdeps/x86_64/sysdep.h | 42 ++++++ + 31 files changed, 75 insertions(+), 770 deletions(-) + +diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S +index 41d4cb8412..4dbbcb4617 100644 +--- a/sysdeps/i386/__longjmp.S ++++ b/sysdeps/i386/__longjmp.S +@@ -19,55 +19,14 @@ + #include + #include + #include +-#include + #include + #include + +-/* Don't restore shadow stack register if +- 1. Shadow stack isn't enabled. Or +- 2. __longjmp is defined for __longjmp_cancel. +- */ +-#if !SHSTK_ENABLED || defined __longjmp +-# undef SHADOW_STACK_POINTER_OFFSET +-#endif +- + .text + ENTRY (__longjmp) + #ifdef PTR_DEMANGLE + movl 4(%esp), %eax /* User's jmp_buf in %eax. */ + +-# ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# else +- xorl %edx, %edx +-# endif +- /* Check and adjust the Shadow-Stack-Pointer. */ +- rdsspd %edx +- /* And compare it with the saved ssp value. */ +- subl SHADOW_STACK_POINTER_OFFSET(%eax), %edx +- je L(skip_ssp) +- /* Count the number of frames to adjust and adjust it +- with incssp instruction. The instruction can adjust +- the ssp by [0..255] value only thus use a loop if +- the number of frames is bigger than 255. */ +- negl %edx +- shrl $2, %edx +- /* NB: We saved Shadow-Stack-Pointer of setjmp. Since we are +- restoring Shadow-Stack-Pointer of setjmp's caller, we +- need to unwind shadow stack by one more frame. */ +- addl $1, %edx +- movl $255, %ebx +-L(loop): +- cmpl %ebx, %edx +- cmovb %edx, %ebx +- incsspd %ebx +- subl %ebx, %edx +- ja L(loop) +-L(skip_ssp): +-# endif + /* Save the return address now. */ + movl (JB_PC*4)(%eax), %edx + /* Get the stack pointer. */ +@@ -98,38 +57,6 @@ L(skip_ssp): + #else + movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ + movl 8(%esp), %eax /* Second argument is return value. */ +-# ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# endif +- /* Check and adjust the Shadow-Stack-Pointer. */ +- xorl %edx, %edx +- /* Get the current ssp. */ +- rdsspd %edx +- /* And compare it with the saved ssp value. */ +- subl SHADOW_STACK_POINTER_OFFSET(%ecx), %edx +- je L(skip_ssp) +- /* Count the number of frames to adjust and adjust it +- with incssp instruction. The instruction can adjust +- the ssp by [0..255] value only thus use a loop if +- the number of frames is bigger than 255. */ +- negl %edx +- shrl $2, %edx +- /* NB: We saved Shadow-Stack-Pointer of setjmp. Since we are +- restoring Shadow-Stack-Pointer of setjmp's caller, we +- need to unwind shadow stack by one more frame. */ +- addl $1, %edx +- movl $255, %ebx +-L(loop): +- cmpl %ebx, %edx +- cmovb %edx, %ebx +- incsspd %ebx +- subl %ebx, %edx +- ja L(loop) +-L(skip_ssp): +-# endif + /* Save the return address now. */ + movl (JB_PC*4)(%ecx), %edx + LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx) +diff --git a/sysdeps/i386/add_n.S b/sysdeps/i386/add_n.S +index 0c2b059774..9ac7de5308 100644 +--- a/sysdeps/i386/add_n.S ++++ b/sysdeps/i386/add_n.S +@@ -40,13 +40,6 @@ ENTRY (__mpn_add_n) + cfi_rel_offset (esi, 0) + movl S2(%esp),%edx + movl SIZE(%esp),%ecx +- +-#if IBT_ENABLED +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +-#endif +- + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax +@@ -58,9 +51,6 @@ ENTRY (__mpn_add_n) + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ +-#if IBT_ENABLED +- leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ +-#endif + #ifdef PIC + /* Calculate start address in loop for PIC. Due to limitations in some + assemblers, Loop-L0-3 cannot be put into the leal */ +@@ -74,40 +64,30 @@ L(0): leal (%eax,%eax,8),%eax + #else + /* Calculate start address in loop for non-PIC. */ + leal (L(oop) - 3)(%eax,%eax,8),%eax +-#endif +-#if IBT_ENABLED +- addl %ebx,%eax /* Adjust for endbr32 */ + #endif + jmp *%eax /* jump into loop */ + ALIGN (3) + L(oop): movl (%esi),%eax + adcl (%edx),%eax + movl %eax,(%edi) +- _CET_ENDBR + movl 4(%esi),%eax + adcl 4(%edx),%eax + movl %eax,4(%edi) +- _CET_ENDBR + movl 8(%esi),%eax + adcl 8(%edx),%eax + movl %eax,8(%edi) +- _CET_ENDBR + movl 12(%esi),%eax + adcl 12(%edx),%eax + movl %eax,12(%edi) +- _CET_ENDBR + movl 16(%esi),%eax + adcl 16(%edx),%eax + movl %eax,16(%edi) +- _CET_ENDBR + movl 20(%esi),%eax + adcl 20(%edx),%eax + movl %eax,20(%edi) +- _CET_ENDBR + movl 24(%esi),%eax + adcl 24(%edx),%eax + movl %eax,24(%edi) +- _CET_ENDBR + movl 28(%esi),%eax + adcl 28(%edx),%eax + movl %eax,28(%edi) +@@ -120,11 +100,6 @@ L(oop): movl (%esi),%eax + sbbl %eax,%eax + negl %eax + +-#if IBT_ENABLED +- popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +-#endif + popl %esi + cfi_adjust_cfa_offset (-4) + cfi_restore (esi) +diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S +index 575339ba21..7a47ab395b 100644 +--- a/sysdeps/i386/bsd-_setjmp.S ++++ b/sysdeps/i386/bsd-_setjmp.S +@@ -23,18 +23,12 @@ + #include + #include + #include +-#include + #include + + #define PARMS 4 /* no space for saved regs */ + #define JMPBUF PARMS + #define SIGMSK JMPBUF+4 + +-/* Don't save shadow stack register if shadow stack isn't enabled. */ +-#if !SHSTK_ENABLED +-# undef SHADOW_STACK_POINTER_OFFSET +-#endif +- + ENTRY (_setjmp) + + xorl %eax, %eax +@@ -58,21 +52,6 @@ ENTRY (_setjmp) + movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ + + movl %eax, JB_SIZE(%edx) /* No signal mask set. */ +-#ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# else +- xorl %ecx, %ecx +-# endif +- /* Get the current Shadow-Stack-Pointer and save it. */ +- rdsspd %ecx +- movl %ecx, SHADOW_STACK_POINTER_OFFSET(%edx) +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +-L(skip_ssp): +-# endif +-#endif + ret + END (_setjmp) + libc_hidden_def (_setjmp) +diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S +index 81482c1484..2d95f08d98 100644 +--- a/sysdeps/i386/bsd-setjmp.S ++++ b/sysdeps/i386/bsd-setjmp.S +@@ -23,18 +23,12 @@ + #include + #include + #include +-#include + #include + + #define PARMS 4 /* no space for saved regs */ + #define JMPBUF PARMS + #define SIGMSK JMPBUF+4 + +-/* Don't save shadow stack register if shadow stack isn't enabled. */ +-#if !SHSTK_ENABLED +-# undef SHADOW_STACK_POINTER_OFFSET +-#endif +- + ENTRY (setjmp) + /* Note that we have to use a non-exported symbol in the next + jump since otherwise gas will emit it as a jump through the +@@ -58,21 +52,6 @@ ENTRY (setjmp) + #endif + movl %ecx, (JB_PC*4)(%eax) + movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */ +-#ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# else +- xorl %ecx, %ecx +-# endif +- /* Get the current Shadow-Stack-Pointer and save it. */ +- rdsspd %ecx +- movl %ecx, SHADOW_STACK_POINTER_OFFSET(%eax) +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +-L(skip_ssp): +-# endif +-#endif + + /* Call __sigjmp_save. */ + pushl $1 +diff --git a/sysdeps/i386/crti.S b/sysdeps/i386/crti.S +index 268ae75725..af132aeea3 100644 +--- a/sysdeps/i386/crti.S ++++ b/sysdeps/i386/crti.S +@@ -61,7 +61,6 @@ + .hidden _init + .type _init, @function + _init: +- _CET_ENDBR + pushl %ebx + /* Maintain 16-byte stack alignment for called functions. */ + subl $8, %esp +@@ -82,7 +81,6 @@ _init: + .hidden _fini + .type _fini, @function + _fini: +- _CET_ENDBR + pushl %ebx + subl $8, %esp + LOAD_PIC_REG (bx) +diff --git a/sysdeps/i386/dl-tlsdesc.S b/sysdeps/i386/dl-tlsdesc.S +index 9522985ee7..0574ce714e 100644 +--- a/sysdeps/i386/dl-tlsdesc.S ++++ b/sysdeps/i386/dl-tlsdesc.S +@@ -37,7 +37,6 @@ + cfi_startproc + .align 16 + _dl_tlsdesc_return: +- _CET_ENDBR + movl 4(%eax), %eax + ret + cfi_endproc +@@ -59,7 +58,6 @@ _dl_tlsdesc_return: + cfi_startproc + .align 16 + _dl_tlsdesc_undefweak: +- _CET_ENDBR + movl 4(%eax), %eax + subl %gs:0, %eax + ret +@@ -101,7 +99,6 @@ _dl_tlsdesc_dynamic (struct tlsdesc *tdp) + cfi_startproc + .align 16 + _dl_tlsdesc_dynamic: +- _CET_ENDBR + /* Like all TLS resolvers, preserve call-clobbered registers. + We need two scratch regs anyway. */ + subl $28, %esp +diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S +index 2d55f373b4..1c569290a5 100644 +--- a/sysdeps/i386/dl-trampoline.S ++++ b/sysdeps/i386/dl-trampoline.S +@@ -26,7 +26,6 @@ + .align 16 + _dl_runtime_resolve: + cfi_adjust_cfa_offset (8) +- _CET_ENDBR + pushl %eax # Preserve registers otherwise clobbered. + cfi_adjust_cfa_offset (4) + pushl %ecx +@@ -53,7 +52,6 @@ _dl_runtime_resolve: + .align 16 + _dl_runtime_resolve_shstk: + cfi_adjust_cfa_offset (8) +- _CET_ENDBR + pushl %eax # Preserve registers otherwise clobbered. + cfi_adjust_cfa_offset (4) + pushl %edx +@@ -78,7 +76,6 @@ _dl_runtime_resolve_shstk: + .align 16 + _dl_runtime_profile_shstk: + cfi_adjust_cfa_offset (8) +- _CET_ENDBR + pushl %esp + cfi_adjust_cfa_offset (4) + addl $8, (%esp) # Account for the pushed PLT data +@@ -123,7 +120,6 @@ _dl_runtime_profile_shstk: + .align 16 + _dl_runtime_profile: + cfi_adjust_cfa_offset (8) +- _CET_ENDBR + pushl %esp + cfi_adjust_cfa_offset (4) + addl $8, (%esp) # Account for the pushed PLT data +diff --git a/sysdeps/i386/i386-mcount.S b/sysdeps/i386/i386-mcount.S +index 8c4ea9e3d5..4888859910 100644 +--- a/sysdeps/i386/i386-mcount.S ++++ b/sysdeps/i386/i386-mcount.S +@@ -29,7 +29,6 @@ + .type C_SYMBOL_NAME(_mcount), @function + .align ALIGNARG(4) + C_LABEL(_mcount) +- _CET_ENDBR + /* Save the caller-clobbered registers. */ + pushl %eax + pushl %ecx +@@ -58,7 +57,6 @@ weak_alias (_mcount, mcount) + .type C_SYMBOL_NAME(__fentry__), @function + .align ALIGNARG(4) + C_LABEL(__fentry__) +- _CET_ENDBR + /* Save the caller-clobbered registers. */ + pushl %eax + pushl %ecx +diff --git a/sysdeps/i386/i686/add_n.S b/sysdeps/i386/i686/add_n.S +index 60c0b8bf8b..ec210df669 100644 +--- a/sysdeps/i386/i686/add_n.S ++++ b/sysdeps/i386/i686/add_n.S +@@ -44,13 +44,6 @@ ENTRY (__mpn_add_n) + cfi_rel_offset (esi, 0) + movl S2(%esp),%edx + movl SIZE(%esp),%ecx +- +-#if IBT_ENABLED +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +-#endif +- + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax +@@ -62,9 +55,6 @@ ENTRY (__mpn_add_n) + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ +-#if IBT_ENABLED +- leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ +-#endif + #ifdef PIC + /* Calculate start address in loop for PIC. */ + leal (L(oop)-L(0)-3)(%eax,%eax,8),%eax +@@ -73,40 +63,30 @@ L(0): + #else + /* Calculate start address in loop for non-PIC. */ + leal (L(oop) - 3)(%eax,%eax,8),%eax +-#endif +-#if IBT_ENABLED +- addl %ebx,%eax /* Adjust for endbr32 */ + #endif + jmp *%eax /* jump into loop */ + ALIGN (3) + L(oop): movl (%esi),%eax + adcl (%edx),%eax + movl %eax,(%edi) +- _CET_ENDBR + movl 4(%esi),%eax + adcl 4(%edx),%eax + movl %eax,4(%edi) +- _CET_ENDBR + movl 8(%esi),%eax + adcl 8(%edx),%eax + movl %eax,8(%edi) +- _CET_ENDBR + movl 12(%esi),%eax + adcl 12(%edx),%eax + movl %eax,12(%edi) +- _CET_ENDBR + movl 16(%esi),%eax + adcl 16(%edx),%eax + movl %eax,16(%edi) +- _CET_ENDBR + movl 20(%esi),%eax + adcl 20(%edx),%eax + movl %eax,20(%edi) +- _CET_ENDBR + movl 24(%esi),%eax + adcl 24(%edx),%eax + movl %eax,24(%edi) +- _CET_ENDBR + movl 28(%esi),%eax + adcl 28(%edx),%eax + movl %eax,28(%edi) +@@ -119,11 +99,6 @@ L(oop): movl (%esi),%eax + sbbl %eax,%eax + negl %eax + +-#if IBT_ENABLED +- popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +-#endif + popl %esi + cfi_adjust_cfa_offset (-4) + cfi_restore (esi) +diff --git a/sysdeps/i386/i686/memcmp.S b/sysdeps/i386/i686/memcmp.S +index e388c3dfbd..9005d6381a 100644 +--- a/sysdeps/i386/i686/memcmp.S ++++ b/sysdeps/i386/i686/memcmp.S +@@ -80,7 +80,7 @@ L(not_1): + LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx) + addl %ecx, %edx + addl %ecx, %esi +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + + ALIGN (4) + L(28bytes): +@@ -326,7 +326,7 @@ L(32bytesormore): + LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx) + addl %ecx, %edx + addl %ecx, %esi +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + + L(load_ecx_28): + addl $0x4, %edx +diff --git a/sysdeps/i386/i686/multiarch/memcmp-sse4.S b/sysdeps/i386/i686/multiarch/memcmp-sse4.S +index e784e21176..449423dd01 100644 +--- a/sysdeps/i386/i686/multiarch/memcmp-sse4.S ++++ b/sysdeps/i386/i686/multiarch/memcmp-sse4.S +@@ -58,7 +58,7 @@ + absolute address. */ \ + addl (%ebx,INDEX,SCALE), %ebx; \ + /* We loaded the jump table and adjusted EDX/ESI. Go. */ \ +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + # else + # define JMPTBL(I, B) I + +@@ -66,7 +66,7 @@ + jump table with relative offsets. INDEX is a register contains the + index into the jump table. SCALE is the scale of INDEX. */ + # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \ +- _CET_NOTRACK jmp *TABLE(,INDEX,SCALE) ++ jmp *TABLE(,INDEX,SCALE) + # endif + + +diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S b/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S +index 19e09314e4..6eb1f54179 100644 +--- a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S ++++ b/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S +@@ -64,7 +64,7 @@ + absolute address. */ \ + addl (%ebx,INDEX,SCALE), %ebx; \ + /* We loaded the jump table. Go. */ \ +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + + # define BRANCH_TO_JMPTBL_ENTRY_VALUE(TABLE) \ + addl $(TABLE - .), %ebx +@@ -72,7 +72,7 @@ + # define BRANCH_TO_JMPTBL_ENTRY_TAIL(TABLE, INDEX, SCALE) \ + addl (%ebx,INDEX,SCALE), %ebx; \ + /* We loaded the jump table. Go. */ \ +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + #else + # define PARMS 4 + # define ENTRANCE +@@ -84,12 +84,12 @@ + absolute offsets. INDEX is a register contains the index into the + jump table. SCALE is the scale of INDEX. */ + # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \ +- _CET_NOTRACK jmp *TABLE(,INDEX,SCALE) ++ jmp *TABLE(,INDEX,SCALE) + + # define BRANCH_TO_JMPTBL_ENTRY_VALUE(TABLE) + + # define BRANCH_TO_JMPTBL_ENTRY_TAIL(TABLE, INDEX, SCALE) \ +- _CET_NOTRACK jmp *TABLE(,INDEX,SCALE) ++ jmp *TABLE(,INDEX,SCALE) + #endif + + .section .text.ssse3,"ax",@progbits +diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S b/sysdeps/i386/i686/multiarch/memcpy-ssse3.S +index 459fa7b304..12edb47b48 100644 +--- a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S ++++ b/sysdeps/i386/i686/multiarch/memcpy-ssse3.S +@@ -64,7 +64,7 @@ + absolute address. */ \ + addl (%ebx, INDEX, SCALE), %ebx; \ + /* We loaded the jump table. Go. */ \ +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + # else + + # define PARMS 4 +@@ -78,7 +78,7 @@ + jump table. SCALE is the scale of INDEX. */ + + # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \ +- _CET_NOTRACK jmp *TABLE(, INDEX, SCALE) ++ jmp *TABLE(, INDEX, SCALE) + # endif + + .section .text.ssse3,"ax",@progbits +diff --git a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S b/sysdeps/i386/i686/multiarch/memset-sse2-rep.S +index 53ac146cd8..cb3c8f5ebf 100644 +--- a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S ++++ b/sysdeps/i386/i686/multiarch/memset-sse2-rep.S +@@ -56,7 +56,7 @@ + add (%ebx,%ecx,4), %ebx; \ + add %ecx, %edx; \ + /* We loaded the jump table and adjusted EDX. Go. */ \ +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + #else + # define ENTRANCE + # define RETURN_END ret +@@ -68,7 +68,7 @@ + absolute offsets. */ + # define BRANCH_TO_JMPTBL_ENTRY(TABLE) \ + add %ecx, %edx; \ +- _CET_NOTRACK jmp *TABLE(,%ecx,4) ++ jmp *TABLE(,%ecx,4) + #endif + + .section .text.sse2,"ax",@progbits +diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/i686/multiarch/memset-sse2.S +index 8566f8b988..30391802d3 100644 +--- a/sysdeps/i386/i686/multiarch/memset-sse2.S ++++ b/sysdeps/i386/i686/multiarch/memset-sse2.S +@@ -56,7 +56,7 @@ + add (%ebx,%ecx,4), %ebx; \ + add %ecx, %edx; \ + /* We loaded the jump table and adjusted EDX. Go. */ \ +- _CET_NOTRACK jmp *%ebx ++ jmp *%ebx + #else + # define ENTRANCE + # define RETURN_END ret +@@ -68,7 +68,7 @@ + absolute offsets. */ + # define BRANCH_TO_JMPTBL_ENTRY(TABLE) \ + add %ecx, %edx; \ +- _CET_NOTRACK jmp *TABLE(,%ecx,4) ++ jmp *TABLE(,%ecx,4) + #endif + + .section .text.sse2,"ax",@progbits +diff --git a/sysdeps/i386/i686/multiarch/strcat-sse2.S b/sysdeps/i386/i686/multiarch/strcat-sse2.S +index 329c3711a7..94a6941fb5 100644 +--- a/sysdeps/i386/i686/multiarch/strcat-sse2.S ++++ b/sysdeps/i386/i686/multiarch/strcat-sse2.S +@@ -49,7 +49,7 @@ + absolute address. */ \ + addl (%ecx,INDEX,SCALE), %ecx; \ + /* We loaded the jump table and adjusted ECX. Go. */ \ +- _CET_NOTRACK jmp *%ecx ++ jmp *%ecx + # else + # define JMPTBL(I, B) I + +@@ -58,7 +58,7 @@ + jump table. SCALE is the scale of INDEX. */ + + # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \ +- _CET_NOTRACK jmp *TABLE(,INDEX,SCALE) ++ jmp *TABLE(,INDEX,SCALE) + # endif + + # ifndef STRCAT +diff --git a/sysdeps/i386/i686/multiarch/strcpy-sse2.S b/sysdeps/i386/i686/multiarch/strcpy-sse2.S +index ab7f544420..135c6c48bb 100644 +--- a/sysdeps/i386/i686/multiarch/strcpy-sse2.S ++++ b/sysdeps/i386/i686/multiarch/strcpy-sse2.S +@@ -64,7 +64,7 @@ + absolute address. */ \ + addl (%ecx,INDEX,SCALE), %ecx; \ + /* We loaded the jump table and adjusted ECX. Go. */ \ +- _CET_NOTRACK jmp *%ecx ++ jmp *%ecx + # else + # define JMPTBL(I, B) I + +@@ -73,7 +73,7 @@ + jump table. SCALE is the scale of INDEX. */ + + # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \ +- _CET_NOTRACK jmp *TABLE(,INDEX,SCALE) ++ jmp *TABLE(,INDEX,SCALE) + # endif + + .text +diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S +index 78513204b4..bb66672259 100644 +--- a/sysdeps/i386/setjmp.S ++++ b/sysdeps/i386/setjmp.S +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -27,11 +26,6 @@ + #define JMPBUF PARMS + #define SIGMSK JMPBUF+4 + +-/* Don't save shadow stack register if shadow stack isn't enabled. */ +-#if !SHSTK_ENABLED +-# undef SHADOW_STACK_POINTER_OFFSET +-#endif +- + ENTRY (__sigsetjmp) + + movl JMPBUF(%esp), %eax +@@ -53,21 +47,6 @@ ENTRY (__sigsetjmp) + movl %ecx, (JB_PC*4)(%eax) + movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */ + +-#ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# else +- xorl %ecx, %ecx +-# endif +- /* Get the current Shadow-Stack-Pointer and save it. */ +- rdsspd %ecx +- movl %ecx, SHADOW_STACK_POINTER_OFFSET(%eax) +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +-L(skip_ssp): +-# endif +-#endif + #if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + xorl %eax, %eax +diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S +index 4c98fc6534..542f070cc1 100644 +--- a/sysdeps/i386/start.S ++++ b/sysdeps/i386/start.S +@@ -132,7 +132,6 @@ ENTRY (_start) + + #if defined PIC && !defined SHARED + __wrap_main: +- _CET_ENDBR + jmp main@PLT + #endif + END (_start) +diff --git a/sysdeps/i386/sub_n.S b/sysdeps/i386/sub_n.S +index 35966c90dc..8147c1331e 100644 +--- a/sysdeps/i386/sub_n.S ++++ b/sysdeps/i386/sub_n.S +@@ -40,13 +40,6 @@ ENTRY (__mpn_sub_n) + cfi_rel_offset (esi, 0) + movl S2(%esp),%edx + movl SIZE(%esp),%ecx +- +-#if IBT_ENABLED +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +-#endif +- + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax +@@ -58,9 +51,6 @@ ENTRY (__mpn_sub_n) + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ +-#if defined __CET__ && (__CET__ & 1) != 0 +- leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ +-#endif + #ifdef PIC + /* Calculate start address in loop for PIC. Due to limitations in some + assemblers, Loop-L0-3 cannot be put into the leal */ +@@ -74,40 +64,30 @@ L(0): leal (%eax,%eax,8),%eax + #else + /* Calculate start address in loop for non-PIC. */ + leal (L(oop) - 3)(%eax,%eax,8),%eax +-#endif +-#if defined __CET__ && (__CET__ & 1) != 0 +- addl %ebx,%eax /* Adjust for endbr32 */ + #endif + jmp *%eax /* jump into loop */ + ALIGN (3) + L(oop): movl (%esi),%eax + sbbl (%edx),%eax + movl %eax,(%edi) +- _CET_ENDBR + movl 4(%esi),%eax + sbbl 4(%edx),%eax + movl %eax,4(%edi) +- _CET_ENDBR + movl 8(%esi),%eax + sbbl 8(%edx),%eax + movl %eax,8(%edi) +- _CET_ENDBR + movl 12(%esi),%eax + sbbl 12(%edx),%eax + movl %eax,12(%edi) +- _CET_ENDBR + movl 16(%esi),%eax + sbbl 16(%edx),%eax + movl %eax,16(%edi) +- _CET_ENDBR + movl 20(%esi),%eax + sbbl 20(%edx),%eax + movl %eax,20(%edi) +- _CET_ENDBR + movl 24(%esi),%eax + sbbl 24(%edx),%eax + movl %eax,24(%edi) +- _CET_ENDBR + movl 28(%esi),%eax + sbbl 28(%edx),%eax + movl %eax,28(%edi) +@@ -120,11 +100,6 @@ L(oop): movl (%esi),%eax + sbbl %eax,%eax + negl %eax + +-#if defined __CET__ && (__CET__ & 1) != 0 +- popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +-#endif + popl %esi + cfi_adjust_cfa_offset (-4) + cfi_restore (esi) +diff --git a/sysdeps/i386/sysdep.h b/sysdeps/i386/sysdep.h +index 0e366974ce..fbc8660f25 100644 +--- a/sysdeps/i386/sysdep.h ++++ b/sysdeps/i386/sysdep.h +@@ -18,6 +18,8 @@ + + #include + ++#define CET_ENABLED 0 ++ + /* It is desirable that the names of PIC thunks match those used by + GCC so that multiple copies are eliminated by the linker. Because + GCC 4.6 and earlier use __i686 in the names, it is necessary to +@@ -37,6 +39,15 @@ + + /* Syntactic details of assembler. */ + ++/* Define an entry point visible from C. */ ++#define ENTRY_P2ALIGN(name, alignment) \ ++ .globl C_SYMBOL_NAME(name); \ ++ .type C_SYMBOL_NAME(name),@function; \ ++ .align ALIGNARG(alignment); \ ++ C_LABEL(name) \ ++ cfi_startproc; \ ++ CALL_MCOUNT ++ + /* If compiled for profiling, call `mcount' at the start of each function. */ + #ifdef PROF + /* The mcount code relies on a normal frame pointer being on the stack +diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S +index ed688c0155..18b5149153 100644 +--- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S ++++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S +@@ -18,14 +18,9 @@ + #include + #include + #include +-#include + #include + #include + +-/* Don't restore shadow stack register if shadow stack isn't enabled. */ +-#if !SHSTK_ENABLED +-# undef SHADOW_STACK_POINTER_OFFSET +-#endif + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +@@ -52,38 +47,6 @@ longjmp_msg: + ENTRY (____longjmp_chk) + movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ + +-#ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# else +- xorl %edx, %edx +-# endif +- /* Check and adjust the Shadow-Stack-Pointer. */ +- rdsspd %edx +- /* And compare it with the saved ssp value. */ +- subl SHADOW_STACK_POINTER_OFFSET(%ecx), %edx +- je L(skip_ssp) +- /* Count the number of frames to adjust and adjust it +- with incssp instruction. The instruction can adjust +- the ssp by [0..255] value only thus use a loop if +- the number of frames is bigger than 255. */ +- negl %edx +- shrl $2, %edx +- /* NB: We saved Shadow-Stack-Pointer of setjmp. Since we are +- restoring Shadow-Stack-Pointer of setjmp's caller, we +- need to unwind shadow stack by one more frame. */ +- addl $1, %edx +- movl $255, %ebx +-L(loop): +- cmpl %ebx, %edx +- cmovb %edx, %ebx +- incsspd %ebx +- subl %ebx, %edx +- ja L(loop) +-L(skip_ssp): +-#endif + /* Save the return address now. */ + movl (JB_PC*4)(%ecx), %edx + /* Get the stack pointer. */ +diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S +index b69a73847b..1a88bdb969 100644 +--- a/sysdeps/unix/sysv/linux/i386/getcontext.S ++++ b/sysdeps/unix/sysv/linux/i386/getcontext.S +@@ -17,7 +17,6 @@ + . */ + + #include +-#include + + #include "ucontext_i.h" + +@@ -42,61 +41,6 @@ ENTRY(__getcontext) + movw %fs, %dx + movl %edx, oFS(%eax) + +-#if SHSTK_ENABLED +- /* Check if shadow stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(no_shstk) +- +- /* Save EAX in EDX. */ +- movl %eax, %edx +- +- xorl %eax, %eax +- cmpl %gs:SSP_BASE_OFFSET, %eax +- jnz L(shadow_stack_bound_recorded) +- +- /* Save EBX in the first scratch register slot. */ +- movl %ebx, oSCRATCH1(%edx) +- +- /* Get the base address and size of the default shadow stack +- which must be the current shadow stack since nothing has +- been recorded yet. */ +- sub $24, %esp +- mov %esp, %ecx +- movl $ARCH_CET_STATUS, %ebx +- movl $__NR_arch_prctl, %eax +- ENTER_KERNEL +- testl %eax, %eax +- jz L(continue_no_err) +- +- /* This should never happen. */ +- hlt +- +-L(continue_no_err): +- /* Restore EBX from the first scratch register slot. */ +- movl oSCRATCH1(%edx), %ebx +- +- /* Record the base of the current shadow stack. */ +- movl 8(%esp), %eax +- movl %eax, %gs:SSP_BASE_OFFSET +- add $24, %esp +- +-L(shadow_stack_bound_recorded): +- /* Load address of the context data structure. */ +- movl 4(%esp), %eax +- +- /* Get the current shadow stack pointer. */ +- rdsspd %edx +- /* NB: Save the caller's shadow stack so that we can jump back +- to the caller directly. */ +- addl $4, %edx +- movl %edx, oSSP(%eax) +- +- /* Save the current shadow stack base in ucontext. */ +- movl %gs:SSP_BASE_OFFSET, %edx +- movl %edx, (oSSP + 4)(%eax) +- +-L(no_shstk): +-#endif + /* We have separate floating-point register content memory on the + stack. We use the __fpregs_mem block in the context. Set the + links up correctly. */ +diff --git a/sysdeps/unix/sysv/linux/i386/makecontext.S b/sysdeps/unix/sysv/linux/i386/makecontext.S +index 346cdd0e0a..1b6713fdf4 100644 +--- a/sysdeps/unix/sysv/linux/i386/makecontext.S ++++ b/sysdeps/unix/sysv/linux/i386/makecontext.S +@@ -17,7 +17,6 @@ + . */ + + #include +-#include + + #include "ucontext_i.h" + +@@ -68,127 +67,6 @@ ENTRY(__makecontext) + jnz 1b + 2: + +-#if SHSTK_ENABLED +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(skip_ssp) +- +- /* Reload the pointer to ucontext. */ +- movl 4(%esp), %eax +- +- /* Shadow stack is enabled. We need to allocate a new shadow +- stack. */ +- subl oSS_SP(%eax), %edx +- shrl $STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT, %edx +- +- /* Align shadow stack size to 8 bytes. */ +- addl $7, %edx +- andl $-8, %edx +- +- /* Store shadow stack size in __ssp[2]. */ +- movl %edx, (oSSP + 8)(%eax) +- +- /* Save ESI in the second scratch register slot. */ +- movl %esi, oSCRATCH2(%eax) +- /* Save EDI in the third scratch register slot. */ +- movl %edi, oSCRATCH3(%eax) +- +- /* Save the pointer to ucontext. */ +- movl %eax, %edi +- +- /* Get the original shadow stack pointer. */ +- rdsspd %esi +- +- /* Align the saved original shadow stack pointer to the next +- 8 byte aligned boundary. */ +- andl $-8, %esi +- +- /* Load the top of the new stack into EDX. */ +- movl oESP(%eax), %edx +- +- /* We need to terminate the FDE here because the unwinder looks +- at ra-1 for unwind information. */ +- cfi_endproc +- +- /* Swap the original stack pointer with the top of the new +- stack. */ +- xchgl %esp, %edx +- +- /* Add 4 bytes since CALL will push the 4-byte return address +- onto stack. */ +- addl $4, %esp +- +- /* Allocate the new shadow stack. Save EBX in the first scratch +- register slot. */ +- movl %ebx, oSCRATCH1(%eax) +- +- /* CET syscall takes 64-bit sizes. */ +- subl $16, %esp +- movl (oSSP + 8)(%eax), %ecx +- movl %ecx, (%esp) +- movl $0, 4(%esp) +- movl %ecx, 8(%esp) +- movl $0, 12(%esp) +- movl %esp, %ecx +- +- movl $ARCH_CET_ALLOC_SHSTK, %ebx +- movl $__NR_arch_prctl, %eax +- ENTER_KERNEL +- testl %eax, %eax +- jne L(hlt) /* This should never happen. */ +- +- /* Copy the base address of the new shadow stack to __ssp[1]. */ +- movl (%esp), %eax +- movl %eax, (oSSP + 4)(%edi) +- +- addl $16, %esp +- +- /* Restore EBX from the first scratch register slot. */ +- movl oSCRATCH1(%edi), %ebx +- +- /* Get the size of the new shadow stack. */ +- movl (oSSP + 8)(%edi), %ecx +- +- /* Use the restore stoken to restore the new shadow stack. */ +- rstorssp -8(%eax, %ecx) +- +- /* Save the restore token at the next 8 byte aligned boundary +- on the original shadow stack. */ +- saveprevssp +- +- /* Push the address of "jmp exitcode" onto the new stack as +- well as the new shadow stack. */ +- call 1f +- jmp L(exitcode) +-1: +- +- /* Get the new shadow stack pointer. */ +- rdsspd %eax +- +- /* Use the restore stoken to restore the original shadow stack. */ +- rstorssp -8(%esi) +- +- /* Save the restore token on the new shadow stack. */ +- saveprevssp +- +- /* Store the new shadow stack pointer in __ssp[0]. */ +- movl %eax, oSSP(%edi) +- +- /* Restore the original stack. */ +- mov %edx, %esp +- +- cfi_startproc +- +- /* Restore ESI from the second scratch register slot. */ +- movl oSCRATCH2(%edi), %esi +- /* Restore EDI from the third scratch register slot. */ +- movl oSCRATCH3(%edi), %edi +- +- ret +- +-L(skip_ssp): +-#endif +- + /* If the function we call returns we must continue with the + context which is given in the uc_link element. To do this + set the return address for the function the user provides +@@ -244,7 +122,6 @@ L(call_exit): + call HIDDEN_JUMPTARGET(exit) + /* The 'exit' call should never return. In case it does cause + the process to terminate. */ +-L(hlt): + hlt + cfi_startproc + END(__makecontext) +diff --git a/sysdeps/unix/sysv/linux/i386/setcontext.S b/sysdeps/unix/sysv/linux/i386/setcontext.S +index ccd79906fd..0602221af2 100644 +--- a/sysdeps/unix/sysv/linux/i386/setcontext.S ++++ b/sysdeps/unix/sysv/linux/i386/setcontext.S +@@ -17,7 +17,6 @@ + . */ + + #include +-#include + + #include "ucontext_i.h" + +@@ -56,6 +55,9 @@ ENTRY(__setcontext) + movl oFS(%eax), %ecx + movw %cx, %fs + ++ /* Fetch the address to return to. */ ++ movl oEIP(%eax), %ecx ++ + /* Load the new stack pointer. */ + cfi_def_cfa (eax, 0) + cfi_offset (edi, oEDI) +@@ -64,103 +66,6 @@ ENTRY(__setcontext) + cfi_offset (ebx, oEBX) + movl oESP(%eax), %esp + +-#if SHSTK_ENABLED +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(no_shstk) +- +- /* If the base of the target shadow stack is the same as the +- base of the current shadow stack, we unwind the shadow +- stack. Otherwise it is a stack switch and we look for a +- restore token. */ +- movl oSSP(%eax), %esi +- movl %esi, %edi +- +- /* Get the base of the target shadow stack. */ +- movl (oSSP + 4)(%eax), %ecx +- cmpl %gs:SSP_BASE_OFFSET, %ecx +- je L(unwind_shadow_stack) +- +- /* Align the saved original shadow stack pointer to the next +- 8 byte aligned boundary. */ +- andl $-8, %esi +- +-L(find_restore_token_loop): +- /* Look for a restore token. */ +- movl -8(%esi), %ebx +- andl $-8, %ebx +- cmpl %esi, %ebx +- je L(restore_shadow_stack) +- +- /* Try the next slot. */ +- subl $8, %esi +- jmp L(find_restore_token_loop) +- +-L(restore_shadow_stack): +- /* Pop return address from the shadow stack since setcontext +- will not return. */ +- movl $1, %ebx +- incsspd %ebx +- +- /* Use the restore stoken to restore the target shadow stack. */ +- rstorssp -8(%esi) +- +- /* Save the restore token on the old shadow stack. NB: This +- restore token may be checked by setcontext or swapcontext +- later. */ +- saveprevssp +- +- /* Record the new shadow stack base that was switched to. */ +- movl (oSSP + 4)(%eax), %ebx +- movl %ebx, %gs:SSP_BASE_OFFSET +- +-L(unwind_shadow_stack): +- rdsspd %ebx +- subl %edi, %ebx +- je L(skip_unwind_shadow_stack) +- negl %ebx +- shrl $2, %ebx +- movl $255, %esi +-L(loop): +- cmpl %esi, %ebx +- cmovb %ebx, %esi +- incsspd %esi +- subl %esi, %ebx +- ja L(loop) +- +-L(skip_unwind_shadow_stack): +- +- /* Load the values of all the preserved registers (except ESP). */ +- movl oEDI(%eax), %edi +- movl oESI(%eax), %esi +- movl oEBP(%eax), %ebp +- movl oEBX(%eax), %ebx +- +- /* Get the return address set with getcontext. */ +- movl oEIP(%eax), %ecx +- +- /* Check if return address is valid for the case when setcontext +- is invoked from L(exitcode) with linked context. */ +- rdsspd %eax +- cmpl (%eax), %ecx +- /* Clear EAX to indicate success. NB: Don't use xorl to keep +- EFLAGS for jne. */ +- movl $0, %eax +- jne L(jmp) +- /* Return to the new context if return address valid. */ +- pushl %ecx +- ret +- +-L(jmp): +- /* Jump to the new context directly. */ +- jmp *%ecx +- +-L(no_shstk): +-#endif +- +- /* Fetch the address to return to. */ +- movl oEIP(%eax), %ecx +- + /* Push the return address on the new stack so we can return there. */ + pushl %ecx + +diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S +index 551df10c91..7800dfefb3 100644 +--- a/sysdeps/unix/sysv/linux/i386/swapcontext.S ++++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S +@@ -17,7 +17,6 @@ + . */ + + #include +-#include + + #include "ucontext_i.h" + +@@ -76,144 +75,6 @@ ENTRY(__swapcontext) + movl oFS(%eax), %edx + movw %dx, %fs + +-#if SHSTK_ENABLED +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET +- jz L(no_shstk) +- +- xorl %eax, %eax +- cmpl %gs:SSP_BASE_OFFSET, %eax +- jnz L(shadow_stack_bound_recorded) +- +- /* Get the base address and size of the default shadow stack +- which must be the current shadow stack since nothing has +- been recorded yet. */ +- sub $24, %esp +- mov %esp, %ecx +- movl $ARCH_CET_STATUS, %ebx +- movl $__NR_arch_prctl, %eax +- ENTER_KERNEL +- testl %eax, %eax +- jz L(continue_no_err) +- +- /* This should never happen. */ +- hlt +- +-L(continue_no_err): +- /* Record the base of the current shadow stack. */ +- movl 8(%esp), %eax +- movl %eax, %gs:SSP_BASE_OFFSET +- add $24, %esp +- +-L(shadow_stack_bound_recorded): +- /* Load address of the context data structure we save in. */ +- movl 4(%esp), %eax +- +- /* Load address of the context data structure we swap in */ +- movl 8(%esp), %edx +- +- /* If we unwind the stack, we can't undo stack unwinding. Just +- save the target shadow stack pointer as the current shadow +- stack pointer. */ +- movl oSSP(%edx), %ecx +- movl %ecx, oSSP(%eax) +- +- /* Save the current shadow stack base in ucontext. */ +- movl %gs:SSP_BASE_OFFSET, %ecx +- movl %ecx, (oSSP + 4)(%eax) +- +- /* If the base of the target shadow stack is the same as the +- base of the current shadow stack, we unwind the shadow +- stack. Otherwise it is a stack switch and we look for a +- restore token. */ +- movl oSSP(%edx), %esi +- movl %esi, %edi +- +- /* Get the base of the target shadow stack. */ +- movl (oSSP + 4)(%edx), %ecx +- cmpl %gs:SSP_BASE_OFFSET, %ecx +- je L(unwind_shadow_stack) +- +- /* Align the saved original shadow stack pointer to the next +- 8 byte aligned boundary. */ +- andl $-8, %esi +- +-L(find_restore_token_loop): +- /* Look for a restore token. */ +- movl -8(%esi), %ebx +- andl $-8, %ebx +- cmpl %esi, %ebx +- je L(restore_shadow_stack) +- +- /* Try the next slot. */ +- subl $8, %esi +- jmp L(find_restore_token_loop) +- +-L(restore_shadow_stack): +- /* The target shadow stack will be restored. Save the current +- shadow stack pointer. */ +- rdsspd %ecx +- movl %ecx, oSSP(%eax) +- +- /* Use the restore stoken to restore the target shadow stack. */ +- rstorssp -8(%esi) +- +- /* Save the restore token on the old shadow stack. NB: This +- restore token may be checked by setcontext or swapcontext +- later. */ +- saveprevssp +- +- /* Record the new shadow stack base that was switched to. */ +- movl (oSSP + 4)(%edx), %ebx +- movl %ebx, %gs:SSP_BASE_OFFSET +- +-L(unwind_shadow_stack): +- rdsspd %ebx +- subl %edi, %ebx +- je L(skip_unwind_shadow_stack) +- negl %ebx +- shrl $2, %ebx +- movl $255, %esi +-L(loop): +- cmpl %esi, %ebx +- cmovb %ebx, %esi +- incsspd %esi +- subl %esi, %ebx +- ja L(loop) +- +-L(skip_unwind_shadow_stack): +- +- /* Load the new stack pointer. */ +- movl oESP(%edx), %esp +- +- /* Load the values of all the preserved registers (except ESP). */ +- movl oEDI(%edx), %edi +- movl oESI(%edx), %esi +- movl oEBP(%edx), %ebp +- movl oEBX(%edx), %ebx +- +- /* Get the return address set with getcontext. */ +- movl oEIP(%edx), %ecx +- +- /* Check if return address is valid for the case when setcontext +- is invoked from L(exitcode) with linked context. */ +- rdsspd %eax +- cmpl (%eax), %ecx +- /* Clear EAX to indicate success. NB: Don't use xorl to keep +- EFLAGS for jne. */ +- movl $0, %eax +- jne L(jmp) +- /* Return to the new context if return address valid. */ +- pushl %ecx +- ret +- +-L(jmp): +- /* Jump to the new context directly. */ +- jmp *%ecx +- +-L(no_shstk): +-#endif +- + /* Fetch the address to return to. */ + movl oEIP(%eax), %ecx + +diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h +index 87de7d640f..46181e2aa2 100644 +--- a/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ b/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -446,9 +446,4 @@ struct libc_do_syscall_args + + #endif /* __ASSEMBLER__ */ + +-/* Each shadow stack slot takes 4 bytes. Assuming that each stack +- frame takes 128 bytes, this is used to compute shadow stack size +- from stack size. */ +-#define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5 +- + #endif /* linux/i386/sysdep.h */ +diff --git a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym +index 1d8608eafc..1dfe03d2cc 100644 +--- a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym ++++ b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym +@@ -22,10 +22,6 @@ oEBP mreg (EBP) + oESP mreg (ESP) + oEBX mreg (EBX) + oEIP mreg (EIP) +-oSCRATCH1 mreg (EAX) +-oSCRATCH2 mreg (ECX) +-oSCRATCH3 mreg (EDX) + oFPREGS mcontext (fpregs) + oSIGMASK ucontext (uc_sigmask) + oFPREGSMEM ucontext (__fpregs_mem) +-oSSP ucontext (__ssp) +diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S +index b23e16a663..bb87cd320f 100644 +--- a/sysdeps/unix/sysv/linux/i386/vfork.S ++++ b/sysdeps/unix/sysv/linux/i386/vfork.S +@@ -20,6 +20,7 @@ + #include + #include + ++ + /* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, +@@ -46,29 +47,6 @@ ENTRY (__vfork) + /* Branch forward if it failed. */ + jae SYSCALL_ERROR_LABEL + +-#if SHSTK_ENABLED +- /* Check if shadow stack is in use. */ +- xorl %edx, %edx +- rdsspd %edx +- testl %edx, %edx +- /* Normal return if shadow stack isn't in use. */ +- je L(no_shstk) +- +- testl %eax, %eax +- /* In parent, normal return. */ +- jnz L(no_shstk) +- +- /* NB: In child, jump back to caller via indirect branch without +- popping shadow stack which is shared with parent. Keep shadow +- stack mismatched so that child returns in the vfork-calling +- function will trigger SIGSEGV. */ +- popl %ecx +- cfi_adjust_cfa_offset (-4) +- jmp *%ecx +- +-L(no_shstk): +-#endif +- + ret + + PSEUDO_END (__vfork) +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index 0b3483a77a..bfe3469f1c 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -21,33 +21,6 @@ + + #include + +-/* __CET__ is defined by GCC with Control-Flow Protection values: +- +-enum cf_protection_level +-{ +- CF_NONE = 0, +- CF_BRANCH = 1 << 0, +- CF_RETURN = 1 << 1, +- CF_FULL = CF_BRANCH | CF_RETURN, +- CF_SET = 1 << 2 +-}; +-*/ +- +-/* Set if CF_BRANCH (IBT) is enabled. */ +-#define X86_FEATURE_1_IBT (1U << 0) +-/* Set if CF_RETURN (SHSTK) is enabled. */ +-#define X86_FEATURE_1_SHSTK (1U << 1) +- +-#ifdef __CET__ +-# define CET_ENABLED 1 +-# define IBT_ENABLED (__CET__ & X86_FEATURE_1_IBT) +-# define SHSTK_ENABLED (__CET__ & X86_FEATURE_1_SHSTK) +-#else +-# define CET_ENABLED 0 +-# define IBT_ENABLED 0 +-# define SHSTK_ENABLED 0 +-#endif +- + /* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need + space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be + aligned to 16 bytes for fxsave and 64 bytes for xsave. */ +@@ -66,27 +39,10 @@ enum cf_protection_level + + /* Syntactic details of assembler. */ + +-#ifdef _CET_ENDBR +-# define _CET_NOTRACK notrack +-#else +-# define _CET_ENDBR +-# define _CET_NOTRACK +-#endif +- + /* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ + #define ALIGNARG(log2) 1< + #include + ++/* __CET__ is defined by GCC with Control-Flow Protection values: ++ ++enum cf_protection_level ++{ ++ CF_NONE = 0, ++ CF_BRANCH = 1 << 0, ++ CF_RETURN = 1 << 1, ++ CF_FULL = CF_BRANCH | CF_RETURN, ++ CF_SET = 1 << 2 ++}; ++*/ ++ ++/* Set if CF_BRANCH (IBT) is enabled. */ ++#define X86_FEATURE_1_IBT (1U << 0) ++/* Set if CF_RETURN (SHSTK) is enabled. */ ++#define X86_FEATURE_1_SHSTK (1U << 1) ++ ++#ifdef __CET__ ++# define CET_ENABLED 1 ++# define SHSTK_ENABLED (__CET__ & X86_FEATURE_1_SHSTK) ++#else ++# define CET_ENABLED 0 ++# define SHSTK_ENABLED 0 ++#endif ++ + #ifdef __ASSEMBLER__ + + /* Syntactic details of assembler. */ + ++#ifdef _CET_ENDBR ++# define _CET_NOTRACK notrack ++#else ++# define _CET_ENDBR ++# define _CET_NOTRACK ++#endif ++ ++/* Define an entry point visible from C. */ ++#define ENTRY_P2ALIGN(name, alignment) \ ++ .globl C_SYMBOL_NAME(name); \ ++ .type C_SYMBOL_NAME(name),@function; \ ++ .align ALIGNARG(alignment); \ ++ C_LABEL(name) \ ++ cfi_startproc; \ ++ _CET_ENDBR; \ ++ CALL_MCOUNT ++ + /* This macro is for setting proper CFI with DW_CFA_expression describing + the register as saved relative to %rsp instead of relative to the CFA. + Expression is DW_OP_drop, DW_OP_breg7 (%rsp is register 7), sleb128 offset +-- +2.27.0 + diff --git a/x32-cet-Support-shadow-stack-during-startup-for-Linu.patch b/x32-cet-Support-shadow-stack-during-startup-for-Linu.patch new file mode 100644 index 0000000..4e85687 --- /dev/null +++ b/x32-cet-Support-shadow-stack-during-startup-for-Linu.patch @@ -0,0 +1,80 @@ +From 4b2071eb023fac3ace9953f0e579565be966f14f Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 22 Jul 2024 17:47:22 -0700 +Subject: [PATCH] x32/cet: Support shadow stack during startup for Linux + 6.10 + +Use RXX_LP in RTLD_START_ENABLE_X86_FEATURES. Support shadow stack during +startup for Linux 6.10: + +commit 2883f01ec37dd8668e7222dfdb5980c86fdfe277 +Author: H.J. Lu +Date: Fri Mar 15 07:04:33 2024 -0700 + + x86/shstk: Enable shadow stacks for x32 + + 1. Add shadow stack support to x32 signal. + 2. Use the 64-bit map_shadow_stack syscall for x32. + 3. Set up shadow stack for x32. + +Add the map_shadow_stack system call to and regenerate +arch-syscall.h. Tested on Intel Tiger Lake with CET enabled x32. There +are no regressions with CET enabled x86-64. There are no changes in CET +enabled x86-64 _dl_start_user. + +Signed-off-by: H.J. Lu +Reviewed-by: Noah Goldstein +(cherry picked from commit 8344c1f5514b1b5b1c8c6e48f4b802653bd23b71) +--- + sysdeps/unix/sysv/linux/x86_64/dl-cet.h | 6 +++--- + sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h | 1 + + sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h | 4 ++++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +index 8fdfdefe53..974632ae3c 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +@@ -92,9 +92,9 @@ dl_cet_ibt_enabled (void) + # Pass GL(dl_x86_feature_1) to _dl_cet_setup_features.\n\ + movl %edx, %edi\n\ + # Align stack for the _dl_cet_setup_features call.\n\ +- andq $-16, %rsp\n\ ++ and $-16, %" RSP_LP "\n\ + call _dl_cet_setup_features\n\ + # Restore %rax and %rsp from %r12 and %r13.\n\ +- movq %r12, %rax\n\ +- movq %r13, %rsp\n\ ++ mov %" R12_LP ", %" RAX_LP "\n\ ++ mov %" R13_LP ", %" RSP_LP "\n\ + " +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index b9db8bc5be..645e85802f 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -151,6 +151,7 @@ + #define __NR_lsetxattr 1073742013 + #define __NR_lstat 1073741830 + #define __NR_madvise 1073741852 ++#define __NR_map_shadow_stack 1073742277 + #define __NR_mbind 1073742061 + #define __NR_membarrier 1073742148 + #define __NR_memfd_create 1073742143 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h +index ae854321a2..8621246c97 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h +@@ -15,6 +15,10 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifndef __NR_map_shadow_stack ++# define __NR_map_shadow_stack 1073742277 ++#endif ++ + /* X32 uses the same 64-bit syscall interface for set_thread_area. */ + #ifndef __NR_set_thread_area + # define __NR_set_thread_area 1073742029 +-- +2.27.0 + diff --git a/x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-BZ-33212.patch b/x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-BZ-33212.patch new file mode 100644 index 0000000..17b090f --- /dev/null +++ b/x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-BZ-33212.patch @@ -0,0 +1,82 @@ +From c69b88fc71aa5657662c5c4f176a51034b029ac4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Thu, 14 Aug 2025 07:03:20 -0700 +Subject: [PATCH] x86-64: Add GLIBC_ABI_DT_X86_64_PLT [BZ #33212] + +When the linker -z mark-plt option is used to add DT_X86_64_PLT, +DT_X86_64_PLTSZ and DT_X86_64_PLTENT, the r_addend field of the +R_X86_64_JUMP_SLOT relocation stores the offset of the indirect +branch instruction. However, glibc versions without the commit: + +commit f8587a61892cbafd98ce599131bf4f103466f084 +Author: H.J. Lu +Date: Fri May 20 19:21:48 2022 -0700 + + x86-64: Ignore r_addend for R_X86_64_GLOB_DAT/R_X86_64_JUMP_SLOT + + According to x86-64 psABI, r_addend should be ignored for R_X86_64_GLOB_DAT + and R_X86_64_JUMP_SLOT. Since linkers always set their r_addends to 0, we + can ignore their r_addends. + + Reviewed-by: Fangrui Song + +won't ignore the r_addend value in the R_X86_64_JUMP_SLOT relocation. +Such programs and shared libraries will fail at run-time randomly. + +Add GLIBC_ABI_DT_X86_64_PLT version to indicate that glibc is compatible +with DT_X86_64_PLT. + +The linker can add the glibc GLIBC_ABI_DT_X86_64_PLT version dependency +whenever -z mark-plt is passed to the linker. The resulting programs and +shared libraries will fail to load at run-time against libc.so without the +GLIBC_ABI_DT_X86_64_PLT version, instead of fail randomly. + +This fixes BZ #33212. + +Signed-off-by: H.J. Lu +Reviewed-by: Sam James +(cherry picked from commit 399384e0c8193e31aea014220ccfa24300ae5938) +--- + sysdeps/x86_64/Makefile | 9 +++++++++ + sysdeps/x86_64/Versions | 5 +++++ + 2 files changed, 14 insertions(+) + +diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile +index 00120ca9ca..105a9a431e 100644 +--- a/sysdeps/x86_64/Makefile ++++ b/sysdeps/x86_64/Makefile +@@ -175,6 +175,15 @@ ifeq (no,$(build-hardcoded-path-in-tests)) + tests-container += tst-glibc-hwcaps-cache + endif + ++tests-special += $(objpfx)check-dt-x86-64-plt.out ++ ++$(objpfx)check-dt-x86-64-plt.out: $(common-objpfx)libc.so ++ LC_ALL=C $(READELF) -V -W $< \ ++ | sed -ne '/.gnu.version_d/, /.gnu.version_r/ p' \ ++ | grep GLIBC_ABI_DT_X86_64_PLT > $@; \ ++ $(evaluate-test) ++generated += check-dt-x86-64-plt.out ++ + endif # $(subdir) == elf + + ifeq ($(subdir),csu) +diff --git a/sysdeps/x86_64/Versions b/sysdeps/x86_64/Versions +index e94758b236..6a989ad3b3 100644 +--- a/sysdeps/x86_64/Versions ++++ b/sysdeps/x86_64/Versions +@@ -5,6 +5,11 @@ libc { + GLIBC_2.13 { + __fentry__; + } ++ GLIBC_ABI_DT_X86_64_PLT { ++ # This symbol is used only for empty version map and will be removed ++ # by scripts/versions.awk. ++ __placeholder_only_for_empty_version_map; ++ } + } + libm { + GLIBC_2.1 { +-- +2.27.0 + diff --git a/x86-64-Allocate-state-buffer-space-for-RDI-RSI-and-R.patch b/x86-64-Allocate-state-buffer-space-for-RDI-RSI-and-R.patch new file mode 100644 index 0000000..ddb0a79 --- /dev/null +++ b/x86-64-Allocate-state-buffer-space-for-RDI-RSI-and-R.patch @@ -0,0 +1,259 @@ +From 2ce5eb61fc2845b7f80dba7c56bd7f7a55b63a59 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 18 Mar 2024 06:40:16 -0700 +Subject: [PATCH] x86-64: Allocate state buffer space for RDI, RSI and + RBX + +_dl_tlsdesc_dynamic preserves RDI, RSI and RBX before realigning stack. +After realigning stack, it saves RCX, RDX, R8, R9, R10 and R11. Define +TLSDESC_CALL_REGISTER_SAVE_AREA to allocate space for RDI, RSI and RBX +to avoid clobbering saved RDI, RSI and RBX values on stack by xsave to +STATE_SAVE_OFFSET(%rsp). + + +==================+<- stack frame start aligned at 8 or 16 bytes + | |<- RDI saved in the red zone + | |<- RSI saved in the red zone + | |<- RBX saved in the red zone + | |<- paddings for stack realignment of 64 bytes + |------------------|<- xsave buffer end aligned at 64 bytes + | |<- + | |<- + | |<- + |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp) + | |<- 8-byte padding for 64-byte alignment + | |<- 8-byte padding for 64-byte alignment + | |<- R11 + | |<- R10 + | |<- R9 + | |<- R8 + | |<- RDX + | |<- RCX + +==================+<- RSP aligned at 64 bytes + +Define TLSDESC_CALL_REGISTER_SAVE_AREA, the total register save area size +for all integer registers by adding 24 to STATE_SAVE_OFFSET since RDI, RSI +and RBX are saved onto stack without adjusting stack pointer first, using +the red-zone. This fixes BZ #31501. +Reviewed-by: Sunil K Pandey + +(cherry picked from commit 717ebfa85c8240d32d0d19d86a484c31c55c9617) +--- + sysdeps/x86/cpu-features.c | 11 ++-- + sysdeps/x86/sysdep.h | 60 ++++++++++++++++++--- + sysdeps/x86_64/tst-gnu2-tls2mod1.S | 87 ++++++++++++++++++++++++++++++ + 3 files changed, 147 insertions(+), 11 deletions(-) + create mode 100644 sysdeps/x86_64/tst-gnu2-tls2mod1.S + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index c693b8a25a..4b75d3bcf2 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -265,7 +265,7 @@ update_active (struct cpu_features *cpu_features) + /* NB: On AMX capable processors, ebx always includes AMX + states. */ + unsigned int xsave_state_full_size +- = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64); ++ = ALIGN_UP (ebx + TLSDESC_CALL_REGISTER_SAVE_AREA, 64); + + cpu_features->xsave_state_size + = xsave_state_full_size; +@@ -355,8 +355,10 @@ update_active (struct cpu_features *cpu_features) + unsigned int amx_size + = (xstate_amx_comp_offsets[31] + + xstate_amx_comp_sizes[31]); +- amx_size = ALIGN_UP (amx_size + STATE_SAVE_OFFSET, +- 64); ++ amx_size ++ = ALIGN_UP ((amx_size ++ + TLSDESC_CALL_REGISTER_SAVE_AREA), ++ 64); + /* Set xsave_state_full_size to the compact AMX + state size for XSAVEC. NB: xsave_state_full_size + is only used in _dl_tlsdesc_dynamic_xsave and +@@ -364,7 +366,8 @@ update_active (struct cpu_features *cpu_features) + cpu_features->xsave_state_full_size = amx_size; + #endif + cpu_features->xsave_state_size +- = ALIGN_UP (size + STATE_SAVE_OFFSET, 64); ++ = ALIGN_UP (size + TLSDESC_CALL_REGISTER_SAVE_AREA, ++ 64); + CPU_FEATURE_SET (cpu_features, XSAVEC); + } + } +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index e41e5401f0..9dab03a488 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -38,14 +38,59 @@ + #ifdef __x86_64__ + /* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need + space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be +- aligned to 16 bytes for fxsave and 64 bytes for xsave. +- +- NB: Is is non-zero because of the 128-byte red-zone. Some registers +- are saved on stack without adjusting stack pointer first. When we +- update stack pointer to allocate more space, we need to take the +- red-zone into account. */ ++ aligned to 16 bytes for fxsave and 64 bytes for xsave. It is non-zero ++ because MOV, instead of PUSH, is used to save registers onto stack. ++ ++ +==================+<- stack frame start aligned at 8 or 16 bytes ++ | |<- paddings for stack realignment of 64 bytes ++ |------------------|<- xsave buffer end aligned at 64 bytes ++ | |<- ++ | |<- ++ | |<- ++ |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp) ++ | |<- 8-byte padding for 64-byte alignment ++ | |<- R9 ++ | |<- R8 ++ | |<- RDI ++ | |<- RSI ++ | |<- RDX ++ | |<- RCX ++ | |<- RAX ++ +==================+<- RSP aligned at 64 bytes ++ ++ */ + # define STATE_SAVE_OFFSET (8 * 7 + 8) + ++/* _dl_tlsdesc_dynamic preserves RDI, RSI and RBX before realigning ++ stack. After realigning stack, it saves RCX, RDX, R8, R9, R10 and ++ R11. Allocate space for RDI, RSI and RBX to avoid clobbering saved ++ RDI, RSI and RBX values on stack by xsave. ++ ++ +==================+<- stack frame start aligned at 8 or 16 bytes ++ | |<- RDI saved in the red zone ++ | |<- RSI saved in the red zone ++ | |<- RBX saved in the red zone ++ | |<- paddings for stack realignment of 64 bytes ++ |------------------|<- xsave buffer end aligned at 64 bytes ++ | |<- ++ | |<- ++ | |<- ++ |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp) ++ | |<- 8-byte padding for 64-byte alignment ++ | |<- 8-byte padding for 64-byte alignment ++ | |<- R11 ++ | |<- R10 ++ | |<- R9 ++ | |<- R8 ++ | |<- RDX ++ | |<- RCX ++ +==================+<- RSP aligned at 64 bytes ++ ++ Define the total register save area size for all integer registers by ++ adding 24 to STATE_SAVE_OFFSET since RDI, RSI and RBX are saved onto ++ stack without adjusting stack pointer first, using the red-zone. */ ++# define TLSDESC_CALL_REGISTER_SAVE_AREA (STATE_SAVE_OFFSET + 24) ++ + /* Save SSE, AVX, AVX512, mask, bound and APX registers. Bound and APX + registers are mutually exclusive. */ + # define STATE_SAVE_MASK \ +@@ -66,8 +111,9 @@ + (STATE_SAVE_MASK | AMX_STATE_SAVE_MASK) + #else + /* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386 +- doesn't have red-zone, use 0 here. */ ++ uses PUSH to save registers onto stack, use 0 here. */ + # define STATE_SAVE_OFFSET 0 ++# define TLSDESC_CALL_REGISTER_SAVE_AREA 0 + + /* Save SSE, AVX, AXV512, mask and bound registers. */ + # define STATE_SAVE_MASK \ +diff --git a/sysdeps/x86_64/tst-gnu2-tls2mod1.S b/sysdeps/x86_64/tst-gnu2-tls2mod1.S +new file mode 100644 +index 0000000000..1d636669ba +--- /dev/null ++++ b/sysdeps/x86_64/tst-gnu2-tls2mod1.S +@@ -0,0 +1,87 @@ ++/* Check if TLSDESC relocation preserves %rdi, %rsi and %rbx. ++ Copyright (C) 2024 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 ++ ++/* On AVX512 machines, OFFSET == 40 caused _dl_tlsdesc_dynamic_xsavec ++ to clobber %rdi, %rsi and %rbx. On Intel AVX CPUs, the state size ++ is 960 bytes and this test didn't fail. It may be due to the unused ++ last 128 bytes. On AMD AVX CPUs, the state size is 832 bytes and ++ this test might fail without the fix. */ ++#ifndef OFFSET ++# define OFFSET 40 ++#endif ++ ++ .text ++ .p2align 4 ++ .globl apply_tls ++ .type apply_tls, @function ++apply_tls: ++ cfi_startproc ++ _CET_ENDBR ++ pushq %rbp ++ cfi_def_cfa_offset (16) ++ cfi_offset (6, -16) ++ movdqu (%RDI_LP), %xmm0 ++ lea tls_var1@TLSDESC(%rip), %RAX_LP ++ mov %RSP_LP, %RBP_LP ++ cfi_def_cfa_register (6) ++ /* Align stack to 64 bytes. */ ++ and $-64, %RSP_LP ++ sub $OFFSET, %RSP_LP ++ pushq %rbx ++ /* Set %ebx to 0xbadbeef. */ ++ movl $0xbadbeef, %ebx ++ movl $0xbadbeef, %esi ++ movq %rdi, saved_rdi(%rip) ++ movq %rsi, saved_rsi(%rip) ++ call *tls_var1@TLSCALL(%RAX_LP) ++ /* Check if _dl_tlsdesc_dynamic preserves %rdi, %rsi and %rbx. */ ++ cmpq saved_rdi(%rip), %rdi ++ jne L(hlt) ++ cmpq saved_rsi(%rip), %rsi ++ jne L(hlt) ++ cmpl $0xbadbeef, %ebx ++ jne L(hlt) ++ add %fs:0, %RAX_LP ++ movups %xmm0, 32(%RAX_LP) ++ movdqu 16(%RDI_LP), %xmm1 ++ mov %RAX_LP, %RBX_LP ++ movups %xmm1, 48(%RAX_LP) ++ lea 32(%RBX_LP), %RAX_LP ++ pop %rbx ++ leave ++ cfi_def_cfa (7, 8) ++ ret ++L(hlt): ++ hlt ++ cfi_endproc ++ .size apply_tls, .-apply_tls ++ .hidden tls_var1 ++ .globl tls_var1 ++ .section .tbss,"awT",@nobits ++ .align 16 ++ .type tls_var1, @object ++ .size tls_var1, 3200 ++tls_var1: ++ .zero 3200 ++ .local saved_rdi ++ .comm saved_rdi,8,8 ++ .local saved_rsi ++ .comm saved_rsi,8,8 ++ .section .note.GNU-stack,"",@progbits +-- +2.27.0 + diff --git a/x86-64-Remove-sysdeps-x86_64-x32-dl-machine.h.patch b/x86-64-Remove-sysdeps-x86_64-x32-dl-machine.h.patch new file mode 100644 index 0000000..8f23f5f --- /dev/null +++ b/x86-64-Remove-sysdeps-x86_64-x32-dl-machine.h.patch @@ -0,0 +1,181 @@ +From 8572a77d9563302fec41bee405b24db204b3e2a4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 22 Jul 2024 17:47:21 -0700 +Subject: [PATCH] x86-64: Remove sysdeps/x86_64/x32/dl-machine.h + +Remove sysdeps/x86_64/x32/dl-machine.h by folding x32 ARCH_LA_PLTENTER, +ARCH_LA_PLTEXIT and RTLD_START into sysdeps/x86_64/dl-machine.h. There +are no regressions on x86-64 nor x32. There are no changes in x86-64 +_dl_start_user. On x32, _dl_start_user changes are + + <_dl_start_user>: + mov %eax,%r12d ++ mov %esp,%r13d + mov (%rsp),%edx + mov %edx,%esi +- mov %esp,%r13d + and $0xfffffff0,%esp + mov 0x0(%rip),%edi # <_dl_start_user+0x14> + lea 0x8(%r13,%rdx,4),%ecx + +Signed-off-by: H.J. Lu +Reviewed-by: Noah Goldstein +(cherry picked from commit 652c6cf26927352fc0e37e4e60c6fc98ddf6d3b4) +--- + sysdeps/x86_64/dl-machine.h | 27 +++++++----- + sysdeps/x86_64/x32/dl-machine.h | 76 --------------------------------- + 2 files changed, 16 insertions(+), 87 deletions(-) + delete mode 100644 sysdeps/x86_64/x32/dl-machine.h + +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index b4159880f3..d35022c45f 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -144,37 +144,37 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + .globl _start\n\ + .globl _dl_start_user\n\ + _start:\n\ +- movq %rsp, %rdi\n\ ++ mov %" RSP_LP ", %" RDI_LP "\n\ + call _dl_start\n\ + _dl_start_user:\n\ + # Save the user entry point address in %r12.\n\ +- movq %rax, %r12\n\ ++ mov %" RAX_LP ", %" R12_LP "\n\ + # Save %rsp value in %r13.\n\ +- movq %rsp, %r13\n\ ++ mov %" RSP_LP ", % " R13_LP "\n\ + "\ + RTLD_START_ENABLE_X86_FEATURES \ + "\ + # Read the original argument count.\n\ +- movq (%rsp), %rdx\n\ ++ mov (%rsp), %" RDX_LP "\n\ + # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\ + # argc -> rsi\n\ +- movq %rdx, %rsi\n\ ++ mov %" RDX_LP ", %" RSI_LP "\n\ + # And align stack for the _dl_init call. \n\ +- andq $-16, %rsp\n\ ++ and $-16, %" RSP_LP "\n\ + # _dl_loaded -> rdi\n\ +- movq _rtld_local(%rip), %rdi\n\ ++ mov _rtld_local(%rip), %" RDI_LP "\n\ + # env -> rcx\n\ +- leaq 16(%r13,%rdx,8), %rcx\n\ ++ lea 2*" LP_SIZE "(%r13,%rdx," LP_SIZE "), %" RCX_LP "\n\ + # argv -> rdx\n\ +- leaq 8(%r13), %rdx\n\ ++ lea " LP_SIZE "(%r13), %" RDX_LP "\n\ + # Clear %rbp to mark outermost frame obviously even for constructors.\n\ + xorl %ebp, %ebp\n\ + # Call the function to run the initializers.\n\ + call _dl_init\n\ + # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\ +- leaq _dl_fini(%rip), %rdx\n\ ++ lea _dl_fini(%rip), %" RDX_LP "\n\ + # And make sure %rsp points to argc stored on the stack.\n\ +- movq %r13, %rsp\n\ ++ mov %" R13_LP ", %" RSP_LP "\n\ + # Jump to the user's entry point.\n\ + jmp *%r12\n\ + .previous\n\ +@@ -239,8 +239,13 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc, + + + /* Names of the architecture-specific auditing callback functions. */ ++#ifdef __LP64__ + #define ARCH_LA_PLTENTER x86_64_gnu_pltenter + #define ARCH_LA_PLTEXIT x86_64_gnu_pltexit ++#else ++#define ARCH_LA_PLTENTER x32_gnu_pltenter ++#define ARCH_LA_PLTEXIT x32_gnu_pltexit ++#endif + + #endif /* !dl_machine_h */ + +diff --git a/sysdeps/x86_64/x32/dl-machine.h b/sysdeps/x86_64/x32/dl-machine.h +deleted file mode 100644 +index 648a11f926..0000000000 +--- a/sysdeps/x86_64/x32/dl-machine.h ++++ /dev/null +@@ -1,76 +0,0 @@ +-/* Machine-dependent ELF dynamic relocation inline functions. x32 version. +- Copyright (C) 2012-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 +- . */ +- +-/* Must allow to be included more than once. +- See #ifdef RESOLVE_MAP in sysdeps/x86_64/dl-machine.h. */ +-#include +- +-#ifndef _X32_DL_MACHINE_H +-#define _X32_DL_MACHINE_H +- +-#undef ARCH_LA_PLTENTER +-#undef ARCH_LA_PLTEXIT +-#undef RTLD_START +- +-/* Names of the architecture-specific auditing callback functions. */ +-#define ARCH_LA_PLTENTER x32_gnu_pltenter +-#define ARCH_LA_PLTEXIT x32_gnu_pltexit +- +-/* Initial entry point code for the dynamic linker. +- The C function `_dl_start' is the real entry point; +- its return value is the user program's entry point. */ +-#define RTLD_START asm ("\n\ +-.text\n\ +- .p2align 4\n\ +-.globl _start\n\ +-.globl _dl_start_user\n\ +-_start:\n\ +- movl %esp, %edi\n\ +- call _dl_start\n\ +-_dl_start_user:\n\ +- # Save the user entry point address in %r12.\n\ +- movl %eax, %r12d\n\ +- # Read the original argument count.\n\ +- movl (%rsp), %edx\n\ +- # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\ +- # argc -> rsi\n\ +- movl %edx, %esi\n\ +- # Save %rsp value in %r13.\n\ +- movl %esp, %r13d\n\ +- # And align stack for the _dl_init call.\n\ +- and $-16, %esp\n\ +- # _dl_loaded -> rdi\n\ +- movl _rtld_local(%rip), %edi\n\ +- # env -> rcx\n\ +- lea 8(%r13,%rdx,4), %ecx\n\ +- # argv -> rdx\n\ +- lea 4(%r13), %edx\n\ +- # Clear %rbp to mark outermost frame obviously even for constructors.\n\ +- xorl %ebp, %ebp\n\ +- # Call the function to run the initializers.\n\ +- call _dl_init\n\ +- # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\ +- lea _dl_fini(%rip), %edx\n\ +- # And make sure %rsp points to argc stored on the stack.\n\ +- movl %r13d, %esp\n\ +- # Jump to the user's entry point.\n\ +- jmp *%r12\n\ +-.previous\n\ +-"); +- +-#endif /* !_X32_DL_MACHINE_H */ +-- +2.27.0 + diff --git a/x86-64-Save-APX-registers-in-ld.so-trampoline.patch b/x86-64-Save-APX-registers-in-ld.so-trampoline.patch new file mode 100644 index 0000000..fcaee2b --- /dev/null +++ b/x86-64-Save-APX-registers-in-ld.so-trampoline.patch @@ -0,0 +1,85 @@ +From 9bb20abcaa75479c6d2c412075536dd57d7ef699 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 16 Feb 2024 07:17:10 -0800 +Subject: [PATCH] x86-64: Save APX registers in ld.so trampoline + +Add APX registers to STATE_SAVE_MASK so that APX registers are saved in +ld.so trampoline. This fixes BZ #31371. + +Also update STATE_SAVE_OFFSET and STATE_SAVE_MASK for i386 which will +be used by i386 _dl_tlsdesc_dynamic. +Reviewed-by: Noah Goldstein + +(cherry picked from commit dfb05f8e704edac70db38c4c8ee700769d91a413) +--- + sysdeps/x86/sysdep.h | 52 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 46 insertions(+), 6 deletions(-) + +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index bfe3469f1c..4e1dd96d4b 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -21,14 +21,54 @@ + + #include + ++/* The extended state feature IDs in the state component bitmap. */ ++#define X86_XSTATE_X87_ID 0 ++#define X86_XSTATE_SSE_ID 1 ++#define X86_XSTATE_AVX_ID 2 ++#define X86_XSTATE_BNDREGS_ID 3 ++#define X86_XSTATE_BNDCFG_ID 4 ++#define X86_XSTATE_K_ID 5 ++#define X86_XSTATE_ZMM_H_ID 6 ++#define X86_XSTATE_ZMM_ID 7 ++#define X86_XSTATE_PKRU_ID 9 ++#define X86_XSTATE_TILECFG_ID 17 ++#define X86_XSTATE_TILEDATA_ID 18 ++#define X86_XSTATE_APX_F_ID 19 ++ ++#ifdef __x86_64__ + /* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need + space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be +- aligned to 16 bytes for fxsave and 64 bytes for xsave. */ +-#define STATE_SAVE_OFFSET (8 * 7 + 8) +- +-/* Save SSE, AVX, AVX512, mask and bound registers. */ +-#define STATE_SAVE_MASK \ +- ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7)) ++ aligned to 16 bytes for fxsave and 64 bytes for xsave. ++ ++ NB: Is is non-zero because of the 128-byte red-zone. Some registers ++ are saved on stack without adjusting stack pointer first. When we ++ update stack pointer to allocate more space, we need to take the ++ red-zone into account. */ ++# define STATE_SAVE_OFFSET (8 * 7 + 8) ++ ++/* Save SSE, AVX, AVX512, mask, bound and APX registers. Bound and APX ++ registers are mutually exclusive. */ ++# define STATE_SAVE_MASK \ ++ ((1 << X86_XSTATE_SSE_ID) \ ++ | (1 << X86_XSTATE_AVX_ID) \ ++ | (1 << X86_XSTATE_BNDREGS_ID) \ ++ | (1 << X86_XSTATE_K_ID) \ ++ | (1 << X86_XSTATE_ZMM_H_ID) \ ++ | (1 << X86_XSTATE_ZMM_ID) \ ++ | (1 << X86_XSTATE_APX_F_ID)) ++#else ++/* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386 ++ doesn't have red-zone, use 0 here. */ ++# define STATE_SAVE_OFFSET 0 ++ ++/* Save SSE, AVX, AXV512, mask and bound registers. */ ++# define STATE_SAVE_MASK \ ++ ((1 << X86_XSTATE_SSE_ID) \ ++ | (1 << X86_XSTATE_AVX_ID) \ ++ | (1 << X86_XSTATE_BNDREGS_ID) \ ++ | (1 << X86_XSTATE_K_ID) \ ++ | (1 << X86_XSTATE_ZMM_H_ID)) ++#endif + + /* Constants for bits in __x86_string_control: */ + +-- +2.27.0 + diff --git a/x86-64-Update-_dl_tlsdesc_dynamic-to-preserve-AMX-re.patch b/x86-64-Update-_dl_tlsdesc_dynamic-to-preserve-AMX-re.patch new file mode 100644 index 0000000..6b76c97 --- /dev/null +++ b/x86-64-Update-_dl_tlsdesc_dynamic-to-preserve-AMX-re.patch @@ -0,0 +1,520 @@ +From 6f076f136680905b56cc816a01674550d2c17bf4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 28 Feb 2024 12:08:03 -0800 +Subject: [PATCH] x86-64: Update _dl_tlsdesc_dynamic to preserve AMX + registers + +_dl_tlsdesc_dynamic should also preserve AMX registers which are +caller-saved. Add X86_XSTATE_TILECFG_ID and X86_XSTATE_TILEDATA_ID +to x86-64 TLSDESC_CALL_STATE_SAVE_MASK. Compute the AMX state size +and save it in xsave_state_full_size which is only used by +_dl_tlsdesc_dynamic_xsave and _dl_tlsdesc_dynamic_xsavec. This fixes +the AMX part of BZ #31372. Tested on AMX processor. + +AMX test is enabled only for compilers with the fix for + +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114098 + +GCC 14 and GCC 11/12/13 branches have the bug fix. +Reviewed-by: Sunil K Pandey + +(cherry picked from commit 9b7091415af47082664717210ac49d51551456ab) +--- + sysdeps/unix/sysv/linux/x86_64/Makefile | 27 ++++++ + .../sysv/linux/x86_64/include/asm/prctl.h | 5 ++ + .../linux/x86_64/tst-gnu2-tls2-amx-mod0.c | 2 + + .../linux/x86_64/tst-gnu2-tls2-amx-mod1.c | 2 + + .../linux/x86_64/tst-gnu2-tls2-amx-mod2.c | 2 + + .../sysv/linux/x86_64/tst-gnu2-tls2-amx.c | 83 +++++++++++++++++++ + .../sysv/linux/x86_64/tst-gnu2-tls2-amx.h | 63 ++++++++++++++ + sysdeps/x86/cpu-features-offsets.sym | 1 + + sysdeps/x86/cpu-features.c | 55 +++++++++++- + sysdeps/x86/include/cpu-features.h | 2 + + sysdeps/x86/sysdep.h | 18 +++- + sysdeps/x86_64/configure | 28 +++++++ + sysdeps/x86_64/configure.ac | 15 ++++ + sysdeps/x86_64/dl-tlsdesc-dynamic.h | 2 +- + 14 files changed, 299 insertions(+), 6 deletions(-) + create mode 100644 sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c + create mode 100644 sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c + create mode 100644 sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c + create mode 100644 sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c + create mode 100644 sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h + +diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile +index 4223feb95f..9a1e7aa646 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/Makefile ++++ b/sysdeps/unix/sysv/linux/x86_64/Makefile +@@ -63,6 +63,33 @@ $(objpfx)libx86-64-isa-level%.os: $(..)/sysdeps/unix/sysv/linux/x86_64/x86-64-is + $(objpfx)libx86-64-isa-level.so: $(objpfx)libx86-64-isa-level-1.so + cp $< $@ + endif ++ ++ifeq (yes,$(have-mamx-tile)) ++tests += \ ++ tst-gnu2-tls2-amx \ ++# tests ++ ++modules-names += \ ++ tst-gnu2-tls2-amx-mod0 \ ++ tst-gnu2-tls2-amx-mod1 \ ++ tst-gnu2-tls2-amx-mod2 \ ++# modules-names ++ ++$(objpfx)tst-gnu2-tls2-amx: $(shared-thread-library) ++$(objpfx)tst-gnu2-tls2-amx.out: \ ++ $(objpfx)tst-gnu2-tls2-amx-mod0.so \ ++ $(objpfx)tst-gnu2-tls2-amx-mod1.so \ ++ $(objpfx)tst-gnu2-tls2-amx-mod2.so ++$(objpfx)tst-gnu2-tls2-amx-mod0.so: $(libsupport) ++$(objpfx)tst-gnu2-tls2-amx-mod1.so: $(libsupport) ++$(objpfx)tst-gnu2-tls2-amx-mod2.so: $(libsupport) ++ ++CFLAGS-tst-gnu2-tls2-amx.c += -mamx-tile ++CFLAGS-tst-gnu2-tls2-amx-mod0.c += -mamx-tile -mtls-dialect=gnu2 ++CFLAGS-tst-gnu2-tls2-amx-mod1.c += -mamx-tile -mtls-dialect=gnu2 ++CFLAGS-tst-gnu2-tls2-amx-mod2.c += -mamx-tile -mtls-dialect=gnu2 ++endif ++ + endif # $(subdir) == elf + + ifneq ($(enable-cet),no) +diff --git a/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h +index 2f511321ad..ef4631bf4b 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h ++++ b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h +@@ -20,3 +20,8 @@ + # define ARCH_SHSTK_SHSTK 0x1 + # define ARCH_SHSTK_WRSS 0x2 + #endif ++ ++#ifndef ARCH_GET_XCOMP_PERM ++# define ARCH_GET_XCOMP_PERM 0x1022 ++# define ARCH_REQ_XCOMP_PERM 0x1023 ++#endif +diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c +new file mode 100644 +index 0000000000..2e0c7b91b7 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c +@@ -0,0 +1,2 @@ ++#include "tst-gnu2-tls2-amx.h" ++#include +diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c +new file mode 100644 +index 0000000000..b8a8ccf1c1 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c +@@ -0,0 +1,2 @@ ++#include "tst-gnu2-tls2-amx.h" ++#include +diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c +new file mode 100644 +index 0000000000..cdf4a8f363 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c +@@ -0,0 +1,2 @@ ++#include "tst-gnu2-tls2-amx.h" ++#include +diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c +new file mode 100644 +index 0000000000..ae4dd82556 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c +@@ -0,0 +1,83 @@ ++/* Test TLSDESC relocation with AMX. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "tst-gnu2-tls2-amx.h" ++ ++extern int arch_prctl (int, ...); ++ ++#define X86_XSTATE_TILECFG_ID 17 ++#define X86_XSTATE_TILEDATA_ID 18 ++ ++/* Initialize tile config. */ ++__attribute__ ((noinline, noclone)) ++static void ++init_tile_config (__tilecfg *tileinfo) ++{ ++ int i; ++ tileinfo->palette_id = 1; ++ tileinfo->start_row = 0; ++ ++ tileinfo->colsb[0] = MAX_ROWS; ++ tileinfo->rows[0] = MAX_ROWS; ++ ++ for (i = 1; i < 4; ++i) ++ { ++ tileinfo->colsb[i] = MAX_COLS; ++ tileinfo->rows[i] = MAX_ROWS; ++ } ++ ++ _tile_loadconfig (tileinfo); ++} ++ ++static bool ++enable_amx (void) ++{ ++ uint64_t bitmask; ++ if (arch_prctl (ARCH_GET_XCOMP_PERM, &bitmask) != 0) ++ return false; ++ ++ if ((bitmask & (1 << X86_XSTATE_TILECFG_ID)) == 0) ++ return false; ++ ++ if (arch_prctl (ARCH_REQ_XCOMP_PERM, X86_XSTATE_TILEDATA_ID) != 0) ++ return false; ++ ++ /* Load tile configuration. */ ++ __tilecfg tile_data = { 0 }; ++ init_tile_config (&tile_data); ++ ++ return true; ++} ++ ++/* An architecture can define it to clobber caller-saved registers in ++ malloc below to verify that the implicit TLSDESC call won't change ++ caller-saved registers. */ ++static void ++clear_tile_register (void) ++{ ++ _tile_zero (2); ++} ++ ++#define MOD(i) "tst-gnu2-tls2-amx-mod" #i ".so" ++#define IS_SUPPORTED() enable_amx () ++#define PREPARE_MALLOC() clear_tile_register () ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h +new file mode 100644 +index 0000000000..1845a3caba +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h +@@ -0,0 +1,63 @@ ++/* Test TLSDESC relocation with AMX. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#define MAX_ROWS 16 ++#define MAX_COLS 64 ++#define MAX 1024 ++#define STRIDE 64 ++ ++typedef struct __tile_config ++{ ++ uint8_t palette_id; ++ uint8_t start_row; ++ uint8_t reserved_0[14]; ++ uint16_t colsb[16]; ++ uint8_t rows[16]; ++} __tilecfg __attribute__ ((aligned (64))); ++ ++/* Initialize int8_t buffer */ ++static inline void ++init_buffer (int8_t *buf, int8_t value) ++{ ++ int rows, colsb, i, j; ++ rows = MAX_ROWS; ++ colsb = MAX_COLS; ++ ++ for (i = 0; i < rows; i++) ++ for (j = 0; j < colsb; j++) ++ buf[i * colsb + j] = value; ++} ++ ++#define BEFORE_TLSDESC_CALL() \ ++ int8_t src[MAX]; \ ++ int8_t res[MAX]; \ ++ /* Initialize src with data */ \ ++ init_buffer (src, 2); \ ++ /* Load tile rows from memory. */ \ ++ _tile_loadd (2, src, STRIDE); ++ ++#define AFTER_TLSDESC_CALL() \ ++ /* Store the tile data to memory. */ \ ++ _tile_stored (2, res, STRIDE); \ ++ _tile_release (); \ ++ TEST_VERIFY_EXIT (memcmp (src, res, sizeof (res)) == 0); +diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym +index 6a8fd29813..21fc88d651 100644 +--- a/sysdeps/x86/cpu-features-offsets.sym ++++ b/sysdeps/x86/cpu-features-offsets.sym +@@ -3,3 +3,4 @@ + #include + + XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size) ++XSAVE_STATE_FULL_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_full_size) +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index 769350814d..c693b8a25a 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -262,6 +262,8 @@ update_active (struct cpu_features *cpu_features) + __cpuid_count (0xd, 0, eax, ebx, ecx, edx); + if (ebx != 0) + { ++ /* NB: On AMX capable processors, ebx always includes AMX ++ states. */ + unsigned int xsave_state_full_size + = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64); + +@@ -275,6 +277,11 @@ update_active (struct cpu_features *cpu_features) + { + unsigned int xstate_comp_offsets[32]; + unsigned int xstate_comp_sizes[32]; ++#ifdef __x86_64__ ++ unsigned int xstate_amx_comp_offsets[32]; ++ unsigned int xstate_amx_comp_sizes[32]; ++ unsigned int amx_ecx; ++#endif + unsigned int i; + + xstate_comp_offsets[0] = 0; +@@ -282,16 +289,39 @@ update_active (struct cpu_features *cpu_features) + xstate_comp_offsets[2] = 576; + xstate_comp_sizes[0] = 160; + xstate_comp_sizes[1] = 256; ++#ifdef __x86_64__ ++ xstate_amx_comp_offsets[0] = 0; ++ xstate_amx_comp_offsets[1] = 160; ++ xstate_amx_comp_offsets[2] = 576; ++ xstate_amx_comp_sizes[0] = 160; ++ xstate_amx_comp_sizes[1] = 256; ++#endif + + for (i = 2; i < 32; i++) + { +- if ((STATE_SAVE_MASK & (1 << i)) != 0) ++ if ((FULL_STATE_SAVE_MASK & (1 << i)) != 0) + { + __cpuid_count (0xd, i, eax, ebx, ecx, edx); +- xstate_comp_sizes[i] = eax; ++#ifdef __x86_64__ ++ /* Include this in xsave_state_full_size. */ ++ amx_ecx = ecx; ++ xstate_amx_comp_sizes[i] = eax; ++ if ((AMX_STATE_SAVE_MASK & (1 << i)) != 0) ++ { ++ /* Exclude this from xsave_state_size. */ ++ ecx = 0; ++ xstate_comp_sizes[i] = 0; ++ } ++ else ++#endif ++ xstate_comp_sizes[i] = eax; + } + else + { ++#ifdef __x86_64__ ++ amx_ecx = 0; ++ xstate_amx_comp_sizes[i] = 0; ++#endif + ecx = 0; + xstate_comp_sizes[i] = 0; + } +@@ -304,6 +334,15 @@ update_active (struct cpu_features *cpu_features) + if ((ecx & (1 << 1)) != 0) + xstate_comp_offsets[i] + = ALIGN_UP (xstate_comp_offsets[i], 64); ++#ifdef __x86_64__ ++ xstate_amx_comp_offsets[i] ++ = (xstate_amx_comp_offsets[i - 1] ++ + xstate_amx_comp_sizes[i - 1]); ++ if ((amx_ecx & (1 << 1)) != 0) ++ xstate_amx_comp_offsets[i] ++ = ALIGN_UP (xstate_amx_comp_offsets[i], ++ 64); ++#endif + } + } + +@@ -312,6 +351,18 @@ update_active (struct cpu_features *cpu_features) + = xstate_comp_offsets[31] + xstate_comp_sizes[31]; + if (size) + { ++#ifdef __x86_64__ ++ unsigned int amx_size ++ = (xstate_amx_comp_offsets[31] ++ + xstate_amx_comp_sizes[31]); ++ amx_size = ALIGN_UP (amx_size + STATE_SAVE_OFFSET, ++ 64); ++ /* Set xsave_state_full_size to the compact AMX ++ state size for XSAVEC. NB: xsave_state_full_size ++ is only used in _dl_tlsdesc_dynamic_xsave and ++ _dl_tlsdesc_dynamic_xsavec. */ ++ cpu_features->xsave_state_full_size = amx_size; ++#endif + cpu_features->xsave_state_size + = ALIGN_UP (size + STATE_SAVE_OFFSET, 64); + CPU_FEATURE_SET (cpu_features, XSAVEC); +diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h +index 2dfab74941..bedea77167 100644 +--- a/sysdeps/x86/include/cpu-features.h ++++ b/sysdeps/x86/include/cpu-features.h +@@ -909,6 +909,8 @@ struct cpu_features + /* The full state size for XSAVE when XSAVEC is disabled by + + GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC ++ ++ and the AMX state size when XSAVEC is available. + */ + unsigned int xsave_state_full_size; + /* Data cache size for use in memory and string routines, typically +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index 9c41b5bbfb..e41e5401f0 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -56,6 +56,14 @@ + | (1 << X86_XSTATE_ZMM_H_ID) \ + | (1 << X86_XSTATE_ZMM_ID) \ + | (1 << X86_XSTATE_APX_F_ID)) ++ ++/* AMX state mask. */ ++# define AMX_STATE_SAVE_MASK \ ++ ((1 << X86_XSTATE_TILECFG_ID) | (1 << X86_XSTATE_TILEDATA_ID)) ++ ++/* States to be included in xsave_state_full_size. */ ++# define FULL_STATE_SAVE_MASK \ ++ (STATE_SAVE_MASK | AMX_STATE_SAVE_MASK) + #else + /* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386 + doesn't have red-zone, use 0 here. */ +@@ -68,13 +76,17 @@ + | (1 << X86_XSTATE_BNDREGS_ID) \ + | (1 << X86_XSTATE_K_ID) \ + | (1 << X86_XSTATE_ZMM_H_ID)) ++ ++/* States to be included in xsave_state_size. */ ++# define FULL_STATE_SAVE_MASK STATE_SAVE_MASK + #endif + + /* States which should be saved for TLSDESC_CALL and TLS_DESC_CALL. +- Compiler assumes that all registers, including x87 FPU stack registers, +- are unchanged after CALL, except for EFLAGS and RAX/EAX. */ ++ Compiler assumes that all registers, including AMX and x87 FPU ++ stack registers, are unchanged after CALL, except for EFLAGS and ++ RAX/EAX. */ + #define TLSDESC_CALL_STATE_SAVE_MASK \ +- (STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID)) ++ (FULL_STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID)) + + /* Constants for bits in __x86_string_control: */ + +diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure +index b4a80b8035..76c7b5943c 100755 +--- a/sysdeps/x86_64/configure ++++ b/sysdeps/x86_64/configure +@@ -99,6 +99,34 @@ fi + config_vars="$config_vars + enable-cet = $enable_cet" + ++# Check if -mamx-tile works properly. ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -mamx-tile works properly" >&5 ++printf %s "checking whether -mamx-tile works properly... " >&6; } ++if test ${libc_cv_x86_have_amx_tile+y} ++then : ++ printf %s "(cached) " >&6 ++else $as_nop ++ cat > conftest.c < ++EOF ++ libc_cv_x86_have_amx_tile=no ++ if { ac_try='${CC-cc} -E $CFLAGS -mamx-tile conftest.c > conftest.i' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ if grep -q __builtin_ia32_ldtilecfg conftest.i; then ++ libc_cv_x86_have_amx_tile=yes ++ fi ++ fi ++ rm -rf conftest* ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_have_amx_tile" >&5 ++printf "%s\n" "$libc_cv_x86_have_amx_tile" >&6; } ++config_vars="$config_vars ++have-mamx-tile = $libc_cv_x86_have_amx_tile" ++ + test -n "$critic_missing" && as_fn_error $? " + *** $critic_missing" "$LINENO" 5 + +diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac +index 937d1aff7e..d767b5a98a 100644 +--- a/sysdeps/x86_64/configure.ac ++++ b/sysdeps/x86_64/configure.ac +@@ -57,5 +57,20 @@ elif test $enable_cet = permissive; then + fi + LIBC_CONFIG_VAR([enable-cet], [$enable_cet]) + ++# Check if -mamx-tile works properly. ++AC_CACHE_CHECK(whether -mamx-tile works properly, ++ libc_cv_x86_have_amx_tile, [dnl ++cat > conftest.c < ++EOF ++ libc_cv_x86_have_amx_tile=no ++ if AC_TRY_COMMAND(${CC-cc} -E $CFLAGS -mamx-tile conftest.c > conftest.i); then ++ if grep -q __builtin_ia32_ldtilecfg conftest.i; then ++ libc_cv_x86_have_amx_tile=yes ++ fi ++ fi ++ rm -rf conftest*]) ++LIBC_CONFIG_VAR([have-mamx-tile], [$libc_cv_x86_have_amx_tile]) ++ + test -n "$critic_missing" && AC_MSG_ERROR([ + *** $critic_missing]) +diff --git a/sysdeps/x86_64/dl-tlsdesc-dynamic.h b/sysdeps/x86_64/dl-tlsdesc-dynamic.h +index 0c2e8d5320..9f02cfc3eb 100644 +--- a/sysdeps/x86_64/dl-tlsdesc-dynamic.h ++++ b/sysdeps/x86_64/dl-tlsdesc-dynamic.h +@@ -99,7 +99,7 @@ _dl_tlsdesc_dynamic: + # endif + #else + /* Allocate stack space of the required size to save the state. */ +- sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP ++ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_FULL_SIZE_OFFSET(%rip), %RSP_LP + #endif + /* Besides rdi and rsi, saved above, save rcx, rdx, r8, r9, + r10 and r11. */ +-- +2.27.0 + diff --git a/x86-64-cet-Check-the-restore-token-in-longjmp.patch b/x86-64-cet-Check-the-restore-token-in-longjmp.patch new file mode 100644 index 0000000..42a8407 --- /dev/null +++ b/x86-64-cet-Check-the-restore-token-in-longjmp.patch @@ -0,0 +1,325 @@ +From 0412cc8b4ff3dbd5d2dc40c44ef88c3b69660a7c Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 2 Jan 2024 07:03:29 -0800 +Subject: [PATCH] x86-64/cet: Check the restore token in longjmp + +setcontext and swapcontext put a restore token on the old shadow stack +which is used to restore the target shadow stack when switching user +contexts. When longjmp from a user context, the target shadow stack +can be different from the current shadow stack and INCSSP can't be +used to restore the shadow stack pointer to the target shadow stack. + +Update longjmp to search for a restore token. If found, use the token +to restore the shadow stack pointer before using INCSSP to pop the +shadow stack. Stop the token search and use INCSSP if the shadow stack +entry value is the same as the current shadow stack pointer. + +It is a user error if there is a shadow stack switch without leaving a +restore token on the old shadow stack. + +The only difference between __longjmp.S and __longjmp_chk.S is that +__longjmp_chk.S has a check for invalid longjmp usages. Merge +__longjmp.S and __longjmp_chk.S by adding the CHECK_INVALID_LONGJMP +macro. +Reviewed-by: Noah Goldstein + +(cherry picked from commit 35694d3416b273ac19d67ffa49b7969f36684ae1) +--- + .../unix/sysv/linux/x86_64/____longjmp_chk.S | 179 ++++-------------- + sysdeps/x86/__longjmp_cancel.S | 3 + + sysdeps/x86_64/__longjmp.S | 47 ++++- + 3 files changed, 84 insertions(+), 145 deletions(-) + +diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +index 1b735bbbb2..1ce15080b2 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S ++++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +@@ -15,18 +15,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +-#include +-#include +-#include + #include +-#include +- +-/* Don't restore shadow stack register if shadow stack isn't enabled. */ +-#if !SHSTK_ENABLED +-# undef SHADOW_STACK_POINTER_OFFSET +-#endif + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +@@ -34,136 +23,48 @@ longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + +- +-//#define __longjmp ____longjmp_chk +- + #ifdef PIC +-# define CALL_FAIL sub $8, %RSP_LP; \ +- cfi_remember_state; \ +- cfi_def_cfa_offset(16); \ +- lea longjmp_msg(%rip), %RDI_LP; \ +- call HIDDEN_JUMPTARGET(__fortify_fail); \ +- nop; \ +- cfi_restore_state ++# define LOAD_MSG lea longjmp_msg(%rip), %RDI_LP + #else +-# define CALL_FAIL sub $8, %RSP_LP; \ +- cfi_remember_state; \ +- cfi_def_cfa_offset(16); \ +- mov $longjmp_msg, %RDI_LP; \ +- call HIDDEN_JUMPTARGET(__fortify_fail); \ +- nop; \ +- cfi_restore_state ++# define LOAD_MSG mov $longjmp_msg, %RDI_LP + #endif + +-/* Jump to the position specified by ENV, causing the +- setjmp call there to return VAL, or 1 if VAL is 0. +- void __longjmp (__jmp_buf env, int val). */ +- .text +-ENTRY(____longjmp_chk) +- /* Restore registers. */ +- mov (JB_RSP*8)(%rdi), %R8_LP +- mov (JB_RBP*8)(%rdi),%R9_LP +- mov (JB_PC*8)(%rdi), %RDX_LP +-#ifdef PTR_DEMANGLE +- PTR_DEMANGLE (%R8_LP) +- PTR_DEMANGLE (%R9_LP) +- PTR_DEMANGLE (%RDX_LP) +-# ifdef __ILP32__ +- /* We ignored the high bits of the %rbp value because only the low +- bits are mangled. But we cannot presume that %rbp is being used +- as a pointer and truncate it, so recover the high bits. */ +- movl (JB_RBP*8 + 4)(%rdi), %eax +- shlq $32, %rax +- orq %rax, %r9 +-# endif +-#endif +- +- cmp %R8_LP, %RSP_LP +- jbe .Lok +- +- /* Save function parameters. */ +- movq %rdi, %r10 +- cfi_register (%rdi, %r10) +- movl %esi, %ebx +- cfi_register (%rsi, %rbx) +- +- xorl %edi, %edi +- lea -sizeSS(%rsp), %RSI_LP +- movl $__NR_sigaltstack, %eax +- syscall +- /* Without working sigaltstack we cannot perform the test. */ +- testl %eax, %eax +- jne .Lok2 +- testl $1, (-sizeSS + oSS_FLAGS)(%rsp) +- jz .Lfail +- +- mov (-sizeSS + oSS_SP)(%rsp), %RAX_LP +- add (-sizeSS + oSS_SIZE)(%rsp), %RAX_LP +- sub %R8_LP, %RAX_LP +- cmp (-sizeSS + oSS_SIZE)(%rsp), %RAX_LP +- jae .Lok2 +- +-.Lfail: CALL_FAIL +- +-.Lok2: movq %r10, %rdi +- cfi_restore (%rdi) +- movl %ebx, %esi +- cfi_restore (%rsi) +- ++#define CHECK_INVALID_LONGJMP \ ++ cmp %R8_LP, %RSP_LP; \ ++ jbe .Lok; \ ++ /* Save function parameters. */ \ ++ movq %rdi, %r10; \ ++ cfi_register (%rdi, %r10); \ ++ movl %esi, %ebx; \ ++ cfi_register (%rsi, %rbx); \ ++ xorl %edi, %edi; \ ++ lea -sizeSS(%rsp), %RSI_LP; \ ++ movl $__NR_sigaltstack, %eax; \ ++ syscall; \ ++ /* Without working sigaltstack we cannot perform the test. */ \ ++ testl %eax, %eax; \ ++ jne .Lok2; \ ++ testl $1, (-sizeSS + oSS_FLAGS)(%rsp); \ ++ jz .Lfail; \ ++ mov (-sizeSS + oSS_SP)(%rsp), %RAX_LP; \ ++ add (-sizeSS + oSS_SIZE)(%rsp), %RAX_LP; \ ++ sub %R8_LP, %RAX_LP; \ ++ cmp (-sizeSS + oSS_SIZE)(%rsp), %RAX_LP; \ ++ jae .Lok2; \ ++.Lfail: \ ++ sub $8, %RSP_LP; \ ++ cfi_remember_state; \ ++ cfi_def_cfa_offset(16); \ ++ LOAD_MSG; \ ++ call HIDDEN_JUMPTARGET(__fortify_fail); \ ++ nop; \ ++ cfi_restore_state; \ ++.Lok2: \ ++ movq %r10, %rdi; \ ++ cfi_restore (%rdi); \ ++ movl %ebx, %esi; \ ++ cfi_restore (%rsi); \ + .Lok: +-#ifdef SHADOW_STACK_POINTER_OFFSET +-# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET +- /* Check if Shadow Stack is enabled. */ +- testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET +- jz L(skip_ssp) +-# else +- xorl %eax, %eax +-# endif +- /* Check and adjust the Shadow-Stack-Pointer. */ +- rdsspq %rax +- /* And compare it with the saved ssp value. */ +- subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax +- je L(skip_ssp) +- /* Count the number of frames to adjust and adjust it +- with incssp instruction. The instruction can adjust +- the ssp by [0..255] value only thus use a loop if +- the number of frames is bigger than 255. */ +- negq %rax +- shrq $3, %rax +- /* NB: We saved Shadow-Stack-Pointer of setjmp. Since we are +- restoring Shadow-Stack-Pointer of setjmp's caller, we +- need to unwind shadow stack by one more frame. */ +- addq $1, %rax +- movl $255, %ebx +-L(loop): +- cmpq %rbx, %rax +- cmovb %rax, %rbx +- incsspq %rbx +- subq %rbx, %rax +- ja L(loop) +-L(skip_ssp): +-#endif +- LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP) +- /* We add unwind information for the target here. */ +- cfi_def_cfa(%rdi, 0) +- cfi_register(%rsp,%r8) +- cfi_register(%rbp,%r9) +- cfi_register(%rip,%rdx) +- cfi_offset(%rbx,JB_RBX*8) +- cfi_offset(%r12,JB_R12*8) +- cfi_offset(%r13,JB_R13*8) +- cfi_offset(%r14,JB_R14*8) +- cfi_offset(%r15,JB_R15*8) +- movq (JB_RBX*8)(%rdi), %rbx +- movq (JB_R12*8)(%rdi), %r12 +- movq (JB_R13*8)(%rdi), %r13 +- movq (JB_R14*8)(%rdi), %r14 +- movq (JB_R15*8)(%rdi), %r15 +- /* Set return value for setjmp. */ +- movl %esi, %eax +- mov %R8_LP, %RSP_LP +- movq %r9,%rbp +- LIBC_PROBE (longjmp_target, 3, +- LP_SIZE@%RDI_LP, -4@%eax, LP_SIZE@%RDX_LP) +- jmpq *%rdx +-END (____longjmp_chk) ++ ++#define __longjmp ____longjmp_chk ++#include <__longjmp.S> +diff --git a/sysdeps/x86/__longjmp_cancel.S b/sysdeps/x86/__longjmp_cancel.S +index b835ba1d10..baca26a1cf 100644 +--- a/sysdeps/x86/__longjmp_cancel.S ++++ b/sysdeps/x86/__longjmp_cancel.S +@@ -16,5 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + ++/* Don't restore shadow stack register for __longjmp_cancel. */ ++#define DO_NOT_RESTORE_SHADOW_STACK ++ + #define __longjmp __longjmp_cancel + #include <__longjmp.S> +diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S +index 9ac075e0a8..1962add362 100644 +--- a/sysdeps/x86_64/__longjmp.S ++++ b/sysdeps/x86_64/__longjmp.S +@@ -22,14 +22,15 @@ + #include + #include + +-/* Don't restore shadow stack register if +- 1. Shadow stack isn't enabled. Or +- 2. __longjmp is defined for __longjmp_cancel. +- */ +-#if !SHSTK_ENABLED || defined __longjmp ++/* Don't restore shadow stack register if shadow stack isn't enabled. */ ++#if !SHSTK_ENABLED || defined DO_NOT_RESTORE_SHADOW_STACK + # undef SHADOW_STACK_POINTER_OFFSET + #endif + ++#ifndef CHECK_INVALID_LONGJMP ++# define CHECK_INVALID_LONGJMP ++#endif ++ + /* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. + void __longjmp (__jmp_buf env, int val). */ +@@ -52,6 +53,9 @@ ENTRY(__longjmp) + orq %rax, %r9 + # endif + #endif ++ ++ CHECK_INVALID_LONGJMP ++ + #ifdef SHADOW_STACK_POINTER_OFFSET + # if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET + /* Check if Shadow Stack is enabled. */ +@@ -63,9 +67,40 @@ ENTRY(__longjmp) + /* Check and adjust the Shadow-Stack-Pointer. */ + /* Get the current ssp. */ + rdsspq %rax ++ /* Save the current ssp. */ ++ movq %rax, %r10 + /* And compare it with the saved ssp value. */ +- subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax ++ movq SHADOW_STACK_POINTER_OFFSET(%rdi), %rcx ++ subq %rcx, %rax + je L(skip_ssp) ++ ++ /* Save the target ssp. */ ++ movq %rcx, %r11 ++ ++L(find_restore_token_loop): ++ /* Look for a restore token. */ ++ movq -8(%rcx), %rbx ++ andq $-8, %rbx ++ cmpq %rcx, %rbx ++ /* Find the restore token. */ ++ je L(restore_shadow_stack) ++ ++ /* Try the next slot. */ ++ subq $8, %rcx ++ /* Stop if the current ssp is found. */ ++ cmpq %rcx, %r10 ++ jne L(find_restore_token_loop) ++ jmp L(no_shadow_stack_token) ++ ++L(restore_shadow_stack): ++ /* Restore the target shadow stack. */ ++ rstorssp -8(%rcx) ++ /* Save the restore token on the old shadow stack. */ ++ saveprevssp ++ rdsspq %rax ++ subq %r11, %rax ++ ++L(no_shadow_stack_token): + /* Count the number of frames to adjust and adjust it + with incssp instruction. The instruction can adjust + the ssp by [0..255] value only thus use a loop if +-- +2.27.0 + diff --git a/x86-64-cet-Make-CET-feature-check-specific-to-Linux-.patch b/x86-64-cet-Make-CET-feature-check-specific-to-Linux-.patch new file mode 100644 index 0000000..a399e54 --- /dev/null +++ b/x86-64-cet-Make-CET-feature-check-specific-to-Linux-.patch @@ -0,0 +1,253 @@ +From e13036cefa50a62aeebf5f2286777124f2edf324 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 10 Jan 2024 08:48:47 -0800 +Subject: [PATCH] x86-64/cet: Make CET feature check specific to + Linux/x86 + +CET feature bits in TCB, which are Linux specific, are used to check if +CET features are active. Move CET feature check to Linux/x86 directory. +Reviewed-by: Noah Goldstein + +(cherry picked from commit f2b65a44714e8fa13c7637cd9413169590795879) +--- + .../sysv/linux/x86/bits/platform/features.h | 48 +++++++++++++++++++ + sysdeps/unix/sysv/linux/x86_64/dl-cet.h | 8 ++++ + .../linux/x86_64/get-cpuid-feature-leaf.c | 24 ++++++++++ + sysdeps/x86/Makefile | 6 ++- + sysdeps/x86/bits/platform/features.h | 27 +++++++++++ + sysdeps/x86/bits/platform/x86.h | 8 ---- + sysdeps/x86/get-cpuid-feature-leaf.c | 8 ---- + sysdeps/x86/sys/platform/x86.h | 19 ++------ + 8 files changed, 115 insertions(+), 33 deletions(-) + create mode 100644 sysdeps/unix/sysv/linux/x86/bits/platform/features.h + create mode 100644 sysdeps/unix/sysv/linux/x86_64/get-cpuid-feature-leaf.c + create mode 100644 sysdeps/x86/bits/platform/features.h + +diff --git a/sysdeps/unix/sysv/linux/x86/bits/platform/features.h b/sysdeps/unix/sysv/linux/x86/bits/platform/features.h +new file mode 100644 +index 0000000000..7704febe92 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86/bits/platform/features.h +@@ -0,0 +1,48 @@ ++/* Inline functions for x86 CPU features. ++ This file is part of the GNU C Library. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_PLATFORM_X86_H ++# error "Never include directly; use instead." ++#endif ++ ++/* Bits in the feature_1 field in TCB. */ ++ ++enum ++{ ++ x86_feature_1_ibt = 1U << 0, ++ x86_feature_1_shstk = 1U << 1 ++}; ++ ++static __inline__ _Bool ++x86_cpu_cet_active (unsigned int __index) ++{ ++#ifdef __x86_64__ ++ unsigned int __feature_1; ++# ifdef __LP64__ ++ __asm__ ("mov %%fs:72, %0" : "=r" (__feature_1)); ++# else ++ __asm__ ("mov %%fs:40, %0" : "=r" (__feature_1)); ++# endif ++ if (__index == x86_cpu_IBT) ++ return __feature_1 & x86_feature_1_ibt; ++ else ++ return __feature_1 & x86_feature_1_shstk; ++#else ++ return false; ++#endif ++} +diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +index ed4a81ea3d..8fdfdefe53 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +@@ -54,6 +54,14 @@ dl_cet_get_cet_status (void) + return status; + } + ++static __always_inline bool ++dl_cet_ibt_enabled (void) ++{ ++ unsigned int feature_1 = THREAD_GETMEM (THREAD_SELF, ++ header.feature_1); ++ return (feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0; ++} ++ + /* Enable shadow stack with a macro to avoid shadow stack underflow. */ + #define ENABLE_X86_CET(cet_feature) \ + if ((cet_feature & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) \ +diff --git a/sysdeps/unix/sysv/linux/x86_64/get-cpuid-feature-leaf.c b/sysdeps/unix/sysv/linux/x86_64/get-cpuid-feature-leaf.c +new file mode 100644 +index 0000000000..39b342463c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/get-cpuid-feature-leaf.c +@@ -0,0 +1,24 @@ ++/* Get CPUID feature leaf. Linux/x86-64 version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifdef __LP64__ ++_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72"); ++#else ++_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40"); ++#endif +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 4f8fcc8e1b..c1b6220992 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -5,7 +5,11 @@ endif + ifeq ($(subdir),elf) + sysdep_routines += get-cpuid-feature-leaf + sysdep-dl-routines += dl-get-cpu-features +-sysdep_headers += sys/platform/x86.h bits/platform/x86.h ++sysdep_headers += \ ++ bits/platform/features.h \ ++ bits/platform/x86.h \ ++ sys/platform/x86.h \ ++# sysdep_headers + + CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags) + CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector) +diff --git a/sysdeps/x86/bits/platform/features.h b/sysdeps/x86/bits/platform/features.h +new file mode 100644 +index 0000000000..f02489266e +--- /dev/null ++++ b/sysdeps/x86/bits/platform/features.h +@@ -0,0 +1,27 @@ ++/* Inline functions for x86 CPU features. ++ This file is part of the GNU C Library. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_PLATFORM_X86_H ++# error "Never include directly; use instead." ++#endif ++ ++static __inline__ _Bool ++x86_cpu_cet_active (unsigned int __index) ++{ ++ return false; ++} +diff --git a/sysdeps/x86/bits/platform/x86.h b/sysdeps/x86/bits/platform/x86.h +index fb8676b968..88ca071aa7 100644 +--- a/sysdeps/x86/bits/platform/x86.h ++++ b/sysdeps/x86/bits/platform/x86.h +@@ -327,11 +327,3 @@ enum + + x86_cpu_PTWRITE = x86_cpu_index_14_ecx_0_ebx + 4 + }; +- +-/* Bits in the feature_1 field in TCB. */ +- +-enum +-{ +- x86_feature_1_ibt = 1U << 0, +- x86_feature_1_shstk = 1U << 1 +-}; +diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c +index f69936b31e..615f3a1920 100644 +--- a/sysdeps/x86/get-cpuid-feature-leaf.c ++++ b/sysdeps/x86/get-cpuid-feature-leaf.c +@@ -19,14 +19,6 @@ + #include + #include + +-#ifdef __x86_64__ +-# ifdef __LP64__ +-_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72"); +-# else +-_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40"); +-# endif +-#endif +- + const struct cpuid_feature * + __x86_get_cpuid_feature_leaf (unsigned int leaf) + { +diff --git a/sysdeps/x86/sys/platform/x86.h b/sysdeps/x86/sys/platform/x86.h +index 89b1b16f22..1913cfe7f4 100644 +--- a/sysdeps/x86/sys/platform/x86.h ++++ b/sysdeps/x86/sys/platform/x86.h +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + __BEGIN_DECLS + +@@ -46,22 +47,8 @@ static __inline__ _Bool + x86_cpu_active (unsigned int __index) + { + if (__index == x86_cpu_IBT || __index == x86_cpu_SHSTK) +- { +-#ifdef __x86_64__ +- unsigned int __feature_1; +-# ifdef __LP64__ +- __asm__ ("mov %%fs:72, %0" : "=r" (__feature_1)); +-# else +- __asm__ ("mov %%fs:40, %0" : "=r" (__feature_1)); +-# endif +- if (__index == x86_cpu_IBT) +- return __feature_1 & x86_feature_1_ibt; +- else +- return __feature_1 & x86_feature_1_shstk; +-#else +- return false; +-#endif +- } ++ return x86_cpu_cet_active (__index); ++ + const struct cpuid_feature *__ptr = __x86_get_cpuid_feature_leaf + (__index / (8 * sizeof (unsigned int) * 4)); + unsigned int __reg +-- +2.27.0 + diff --git a/x86-64-cet-Move-check-cet.awk-to-x86_64.patch b/x86-64-cet-Move-check-cet.awk-to-x86_64.patch new file mode 100644 index 0000000..a8611f7 --- /dev/null +++ b/x86-64-cet-Move-check-cet.awk-to-x86_64.patch @@ -0,0 +1,33 @@ +From 90ee4db1bfaafa5892ef52273719cb10178a750b Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 9 Jan 2024 12:23:26 -0800 +Subject: [PATCH] x86-64/cet: Move check-cet.awk to x86_64 + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 7d544dd049a2e3f1480b668f51b72dcc89e376ab) +--- + sysdeps/x86_64/Makefile | 2 +- + sysdeps/{x86 => x86_64}/check-cet.awk | 0 + 2 files changed, 1 insertion(+), 1 deletion(-) + rename sysdeps/{x86 => x86_64}/check-cet.awk (100%) + +diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile +index 48182b437b..36be2f6d56 100644 +--- a/sysdeps/x86_64/Makefile ++++ b/sysdeps/x86_64/Makefile +@@ -442,7 +442,7 @@ $(cet-built-dso:=.note): %.note: % + mv -f $@T $@ + common-generated += $(cet-built-dso:$(common-objpfx)%=%.note) + +-$(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \ ++$(objpfx)check-cet.out: $(..)sysdeps/x86_64/check-cet.awk \ + $(cet-built-dso:=.note) + LC_ALL=C $(AWK) -f $^ > $@; \ + $(evaluate-test) +diff --git a/sysdeps/x86/check-cet.awk b/sysdeps/x86_64/check-cet.awk +similarity index 100% +rename from sysdeps/x86/check-cet.awk +rename to sysdeps/x86_64/check-cet.awk +-- +2.27.0 + diff --git a/x86-64-cet-Move-dl-cet.-ch-to-x86_64-directories.patch b/x86-64-cet-Move-dl-cet.-ch-to-x86_64-directories.patch new file mode 100644 index 0000000..083ec41 --- /dev/null +++ b/x86-64-cet-Move-dl-cet.-ch-to-x86_64-directories.patch @@ -0,0 +1,164 @@ +From 5d884f894978c74b3fd6e4f7948688138ca2d8f6 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 9 Jan 2024 12:23:25 -0800 +Subject: [PATCH] x86-64/cet: Move dl-cet.[ch] to x86_64 directories + +Since CET is only enabled for x86-64, move dl-cet.[ch] to x86_64 +directories. +Reviewed-by: Adhemerval Zanella + +(cherry picked from commit a1bbee9fd17a84d4b550f8405d5e4d31ff24f87d) +--- + sysdeps/unix/sysv/linux/x86/dl-cet.h | 63 ------------------------- + sysdeps/unix/sysv/linux/x86_64/dl-cet.h | 47 +++++++++++++++++- + sysdeps/{x86 => x86_64}/dl-cet.c | 4 +- + 3 files changed, 48 insertions(+), 66 deletions(-) + delete mode 100644 sysdeps/unix/sysv/linux/x86/dl-cet.h + rename sysdeps/{x86 => x86_64}/dl-cet.c (99%) + +diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h +deleted file mode 100644 +index 6ad5e03f69..0000000000 +--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h ++++ /dev/null +@@ -1,63 +0,0 @@ +-/* Linux/x86 CET initializers function. +- Copyright (C) 2018-2023 Free Software Foundation, Inc. +- +- 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 +- +-static __always_inline int +-dl_cet_disable_cet (unsigned int cet_feature) +-{ +- if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) +- return -1; +- long long int kernel_feature = ARCH_SHSTK_SHSTK; +- return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_DISABLE, +- kernel_feature); +-} +- +-static __always_inline int +-dl_cet_lock_cet (unsigned int cet_feature) +-{ +- if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) +- return -1; +- /* Lock all SHSTK features. */ +- long long int kernel_feature = -1; +- return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK, +- kernel_feature); +-} +- +-static __always_inline unsigned int +-dl_cet_get_cet_status (void) +-{ +- unsigned long long kernel_feature; +- unsigned int status = 0; +- if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS, +- &kernel_feature) == 0) +- { +- if ((kernel_feature & ARCH_SHSTK_SHSTK) != 0) +- status = GNU_PROPERTY_X86_FEATURE_1_SHSTK; +- } +- return status; +-} +- +-/* Enable shadow stack with a macro to avoid shadow stack underflow. */ +-#define ENABLE_X86_CET(cet_feature) \ +- if ((cet_feature & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) \ +- { \ +- long long int kernel_feature = ARCH_SHSTK_SHSTK; \ +- INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_ENABLE, \ +- kernel_feature); \ +- } +diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +index e23e05c6b8..64022a631a 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +@@ -15,8 +15,53 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++#include + #include +-#include_next ++ ++static __always_inline int ++dl_cet_disable_cet (unsigned int cet_feature) ++{ ++ if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ return -1; ++ long long int kernel_feature = ARCH_SHSTK_SHSTK; ++ return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_DISABLE, ++ kernel_feature); ++} ++ ++static __always_inline int ++dl_cet_lock_cet (unsigned int cet_feature) ++{ ++ if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ return -1; ++ /* Lock all SHSTK features. */ ++ long long int kernel_feature = -1; ++ return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK, ++ kernel_feature); ++} ++ ++static __always_inline unsigned int ++dl_cet_get_cet_status (void) ++{ ++ unsigned long long kernel_feature; ++ unsigned int status = 0; ++ if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS, ++ &kernel_feature) == 0) ++ { ++ if ((kernel_feature & ARCH_SHSTK_SHSTK) != 0) ++ status = GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ } ++ return status; ++} ++ ++/* Enable shadow stack with a macro to avoid shadow stack underflow. */ ++#define ENABLE_X86_CET(cet_feature) \ ++ if ((cet_feature & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) \ ++ { \ ++ long long int kernel_feature = ARCH_SHSTK_SHSTK; \ ++ INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_ENABLE, \ ++ kernel_feature); \ ++ } + + #define X86_STRINGIFY_1(x) #x + #define X86_STRINGIFY(x) X86_STRINGIFY_1 (x) +diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86_64/dl-cet.c +similarity index 99% +rename from sysdeps/x86/dl-cet.c +rename to sysdeps/x86_64/dl-cet.c +index 82167ebf50..1297c09f84 100644 +--- a/sysdeps/x86/dl-cet.c ++++ b/sysdeps/x86_64/dl-cet.c +@@ -1,5 +1,5 @@ +-/* x86 CET initializers function. +- Copyright (C) 2018-2023 Free Software Foundation, Inc. ++/* x86-64 CET initializers function. ++ Copyright (C) 2018-2024 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public +-- +2.27.0 + diff --git a/x86-Modularize-sysdeps-x86-dl-cet.c.patch b/x86-Modularize-sysdeps-x86-dl-cet.c.patch new file mode 100644 index 0000000..9eaa31e --- /dev/null +++ b/x86-Modularize-sysdeps-x86-dl-cet.c.patch @@ -0,0 +1,513 @@ +From cc47b519301bfd85ec3e50bbb61ab6fea855b82c Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 24 Mar 2023 13:20:06 -0700 +Subject: [PATCH] x86: Modularize sysdeps/x86/dl-cet.c + +Improve readability and make maintenance easier for dl-feature.c by +modularizing sysdeps/x86/dl-cet.c: +1. Support processors with: + a. Only IBT. Or + b. Only SHSTK. Or + c. Both IBT and SHSTK. +2. Lock CET features only if IBT or SHSTK are enabled and are not +enabled permissively. + +(cherry picked from commit c04035809a393c0c6f1cc523df6b316b05fdb50f) +--- + sysdeps/x86/dl-cet.c | 456 ++++++++++++++++++++++++++----------------- + 1 file changed, 280 insertions(+), 176 deletions(-) + +diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c +index 60ea1cb558..67c51ee8c2 100644 +--- a/sysdeps/x86/dl-cet.c ++++ b/sysdeps/x86/dl-cet.c +@@ -32,206 +32,310 @@ + # error GNU_PROPERTY_X86_FEATURE_1_SHSTK != X86_FEATURE_1_SHSTK + #endif + +-/* Check if object M is compatible with CET. */ ++struct dl_cet_info ++{ ++ const char *program; ++ ++ /* Check how IBT and SHSTK should be enabled. */ ++ enum dl_x86_cet_control enable_ibt_type; ++ enum dl_x86_cet_control enable_shstk_type; ++ ++ /* If IBT and SHSTK were previously enabled. */ ++ unsigned int feature_1_enabled; ++ ++ /* If IBT and SHSTK should be enabled. */ ++ unsigned int enable_feature_1; ++ ++ /* If there are any legacy shared object. */ ++ unsigned int feature_1_legacy; ++ ++ /* Which shared object is the first legacy shared object. */ ++ unsigned int feature_1_legacy_ibt; ++ unsigned int feature_1_legacy_shstk; ++}; ++ ++/* Check if the object M and its dependencies are legacy object. */ + + static void +-dl_cet_check (struct link_map *m, const char *program) ++dl_check_legacy_object (struct link_map *m, ++ struct dl_cet_info *info) + { +- /* Check how IBT should be enabled. */ +- enum dl_x86_cet_control enable_ibt_type +- = GL(dl_x86_feature_control).ibt; +- /* Check how SHSTK should be enabled. */ +- enum dl_x86_cet_control enable_shstk_type +- = GL(dl_x86_feature_control).shstk; +- +- /* No legacy object check if both IBT and SHSTK are always on. */ +- if (enable_ibt_type == cet_always_on +- && enable_shstk_type == cet_always_on) ++ unsigned int i; ++ struct link_map *l = NULL; ++ ++ i = m->l_searchlist.r_nlist; ++ while (i-- > 0) + { +- THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)); +- return; +- } ++ /* Check each shared object to see if IBT and SHSTK are enabled. */ ++ l = m->l_initfini[i]; + +- /* Check if IBT is enabled by kernel. */ +- bool ibt_enabled +- = (GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0; +- /* Check if SHSTK is enabled by kernel. */ +- bool shstk_enabled +- = (GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0; ++ if (l->l_init_called) ++ continue; + +- if (ibt_enabled || shstk_enabled) +- { +- struct link_map *l = NULL; +- unsigned int ibt_legacy = 0, shstk_legacy = 0; +- bool found_ibt_legacy = false, found_shstk_legacy = false; +- +- /* Check if IBT and SHSTK are enabled in object. */ +- bool enable_ibt = (ibt_enabled +- && enable_ibt_type != cet_always_off); +- bool enable_shstk = (shstk_enabled +- && enable_shstk_type != cet_always_off); +- if (program) ++#ifdef SHARED ++ /* Skip check for ld.so since it has the features enabled. The ++ features will be disabled later if they are not enabled in ++ executable. */ ++ if (l == &GL(dl_rtld_map) ++ || l->l_real == &GL(dl_rtld_map) ++ || (info->program != NULL && l == m)) ++ continue; ++#endif ++ ++ /* IBT and SHSTK set only if enabled in executable and all DSOs. ++ NB: cet_always_on is handled outside of the loop. */ ++ info->enable_feature_1 &= ((l->l_x86_feature_1_and ++ & (GNU_PROPERTY_X86_FEATURE_1_IBT ++ | GNU_PROPERTY_X86_FEATURE_1_SHSTK)) ++ | ~(GNU_PROPERTY_X86_FEATURE_1_IBT ++ | GNU_PROPERTY_X86_FEATURE_1_SHSTK)); ++ if ((info->feature_1_legacy ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) == 0 ++ && ((info->enable_feature_1 ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) ++ != (info->feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_IBT))) + { +- /* Enable IBT and SHSTK only if they are enabled in executable. +- NB: IBT and SHSTK may be disabled by environment variable: +- +- GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK +- */ +- enable_ibt &= (CPU_FEATURE_USABLE (IBT) +- && (enable_ibt_type == cet_always_on +- || (m->l_x86_feature_1_and +- & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0)); +- enable_shstk &= (CPU_FEATURE_USABLE (SHSTK) +- && (enable_shstk_type == cet_always_on +- || (m->l_x86_feature_1_and +- & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0)); ++ info->feature_1_legacy_ibt = i; ++ info->feature_1_legacy |= GNU_PROPERTY_X86_FEATURE_1_IBT; + } + +- /* ld.so is CET-enabled by kernel. But shared objects may not +- support IBT nor SHSTK. */ +- if (enable_ibt || enable_shstk) +- { +- unsigned int i; ++ if ((info->feature_1_legacy ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK) == 0 ++ && ((info->enable_feature_1 ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ != (info->feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK))) ++ { ++ info->feature_1_legacy_shstk = i; ++ info->feature_1_legacy |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ } ++ } + +- i = m->l_searchlist.r_nlist; +- while (i-- > 0) +- { +- /* Check each shared object to see if IBT and SHSTK are +- enabled. */ +- l = m->l_initfini[i]; ++ /* Handle cet_always_on. */ ++ if ((info->feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0 ++ && info->enable_ibt_type == cet_always_on) ++ { ++ info->feature_1_legacy &= ~GNU_PROPERTY_X86_FEATURE_1_IBT; ++ info->enable_feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT; ++ } + +- if (l->l_init_called) +- continue; ++ if ((info->feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0 ++ && info->enable_shstk_type == cet_always_on) ++ { ++ info->feature_1_legacy &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ info->enable_feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ } ++} + + #ifdef SHARED +- /* Skip CET check for ld.so since ld.so is CET-enabled. +- CET will be disabled later if CET isn't enabled in +- executable. */ +- if (l == &GL(dl_rtld_map) +- || l->l_real == &GL(dl_rtld_map) +- || (program && l == m)) +- continue; ++/* Enable IBT and SHSTK only if they are enabled in executable. Set ++ feature bits properly at the start of the program. */ ++ ++static void ++dl_cet_check_startup (struct link_map *m, struct dl_cet_info *info) ++{ ++ /* NB: IBT and SHSTK may be disabled by environment variable: ++ ++ GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK. ++ */ ++ if (CPU_FEATURE_USABLE (IBT)) ++ { ++ if (info->enable_ibt_type == cet_always_on) ++ info->enable_feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT; ++ else ++ info->enable_feature_1 &= ((m->l_x86_feature_1_and ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) ++ | ~GNU_PROPERTY_X86_FEATURE_1_IBT); ++ } ++ else ++ info->enable_feature_1 &= ~GNU_PROPERTY_X86_FEATURE_1_IBT; ++ ++ if (CPU_FEATURE_USABLE (SHSTK)) ++ { ++ if (info->enable_shstk_type == cet_always_on) ++ info->enable_feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ else ++ info->enable_feature_1 &= ((m->l_x86_feature_1_and ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ | ~GNU_PROPERTY_X86_FEATURE_1_SHSTK); ++ } ++ else ++ info->enable_feature_1 &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ ++ if (info->enable_feature_1 != 0) ++ dl_check_legacy_object (m, info); ++ ++ unsigned int disable_feature_1 ++ = info->enable_feature_1 ^ info->feature_1_enabled; ++ if (disable_feature_1 != 0) ++ { ++ /* Disable features in the kernel because of legacy objects or ++ cet_always_off. */ ++ if (dl_cet_disable_cet (disable_feature_1) != 0) ++ _dl_fatal_printf ("%s: can't disable x86 Features\n", ++ info->program); ++ ++ /* Clear the disabled bits. Sync dl_x86_feature_1 and ++ info->feature_1_enabled with info->enable_feature_1. */ ++ info->feature_1_enabled = info->enable_feature_1; ++ GL(dl_x86_feature_1) = info->enable_feature_1; ++ } ++ ++ if (HAS_CPU_FEATURE (IBT) || HAS_CPU_FEATURE (SHSTK)) ++ { ++ /* Lock CET features only if IBT or SHSTK are enabled and are not ++ enabled permissively. */ ++ unsigned int feature_1_lock = 0; ++ ++ if (((info->feature_1_enabled & GNU_PROPERTY_X86_FEATURE_1_IBT) ++ != 0) ++ && info->enable_ibt_type != cet_permissive) ++ feature_1_lock |= GNU_PROPERTY_X86_FEATURE_1_IBT; ++ ++ if (((info->feature_1_enabled & GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ != 0) ++ && info->enable_shstk_type != cet_permissive) ++ feature_1_lock |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ ++ if (feature_1_lock != 0 ++ && dl_cet_lock_cet () != 0) ++ _dl_fatal_printf ("%s: can't lock CET\n", info->program); ++ } ++ ++ THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)); ++} + #endif + +- /* IBT is enabled only if it is enabled in executable as +- well as all shared objects. */ +- enable_ibt &= (enable_ibt_type == cet_always_on +- || (l->l_x86_feature_1_and +- & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0); +- if (!found_ibt_legacy && enable_ibt != ibt_enabled) +- { +- found_ibt_legacy = true; +- ibt_legacy = i; +- } +- +- /* SHSTK is enabled only if it is enabled in executable as +- well as all shared objects. */ +- enable_shstk &= (enable_shstk_type == cet_always_on +- || (l->l_x86_feature_1_and +- & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0); +- if (enable_shstk != shstk_enabled) +- { +- found_shstk_legacy = true; +- shstk_legacy = i; +- } +- } +- } ++/* Check feature bits when dlopening the shared object M. */ ++ ++static void ++dl_cet_check_dlopen (struct link_map *m, struct dl_cet_info *info) ++{ ++ /* Check if there are any legacy objects loaded. */ ++ if (info->enable_feature_1 != 0) ++ { ++ dl_check_legacy_object (m, info); + +- bool cet_feature_changed = false; ++ /* Skip if there are no legacy shared objects loaded. */ ++ if (info->feature_1_legacy == 0) ++ return; ++ } + +- if (enable_ibt != ibt_enabled || enable_shstk != shstk_enabled) +- { +- if (!program) +- { +- if (enable_ibt_type != cet_permissive) +- { +- /* When IBT is enabled, we cannot dlopen a shared +- object without IBT. */ +- if (found_ibt_legacy) +- _dl_signal_error (0, +- m->l_initfini[ibt_legacy]->l_name, +- "dlopen", +- N_("rebuild shared object with IBT support enabled")); +- } +- +- if (enable_shstk_type != cet_permissive) +- { +- /* When SHSTK is enabled, we cannot dlopen a shared +- object without SHSTK. */ +- if (found_shstk_legacy) +- _dl_signal_error (0, +- m->l_initfini[shstk_legacy]->l_name, +- "dlopen", +- N_("rebuild shared object with SHSTK support enabled")); +- } +- +- if (enable_ibt_type != cet_permissive +- && enable_shstk_type != cet_permissive) +- return; +- } +- +- /* Disable IBT and/or SHSTK if they are enabled by kernel, but +- disabled in executable or shared objects. */ +- unsigned int cet_feature = 0; +- +- if (!enable_ibt) +- cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT; +- if (!enable_shstk) +- cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; +- +- int res = dl_cet_disable_cet (cet_feature); +- if (res != 0) +- { +- if (program) +- _dl_fatal_printf ("%s: can't disable CET\n", program); +- else +- { +- if (found_ibt_legacy) +- l = m->l_initfini[ibt_legacy]; +- else +- l = m->l_initfini[shstk_legacy]; +- _dl_signal_error (-res, l->l_name, "dlopen", +- N_("can't disable CET")); +- } +- } +- +- /* Clear the disabled bits in dl_x86_feature_1. */ +- GL(dl_x86_feature_1) &= ~cet_feature; +- +- cet_feature_changed = true; +- } ++ unsigned int disable_feature_1 = 0; ++ unsigned int legacy_obj = 0; ++ const char *msg = NULL; + +-#ifdef SHARED +- if (program && (ibt_enabled || shstk_enabled)) ++ if ((info->feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0 ++ && (info->feature_1_legacy ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0) ++ { ++ if (info->enable_ibt_type != cet_permissive) + { +- if ((!ibt_enabled +- || enable_ibt_type != cet_permissive) +- && (!shstk_enabled +- || enable_shstk_type != cet_permissive)) +- { +- /* Lock CET if IBT or SHSTK is enabled in executable unless +- IBT or SHSTK is enabled permissively. */ +- int res = dl_cet_lock_cet (); +- if (res != 0) +- _dl_fatal_printf ("%s: can't lock CET\n", program); +- } +- +- /* Set feature_1 if IBT or SHSTK is enabled in executable. */ +- cet_feature_changed = true; ++ legacy_obj = info->feature_1_legacy_ibt; ++ msg = N_("rebuild shared object with IBT support enabled"); + } +-#endif ++ else ++ disable_feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT; ++ } + +- if (cet_feature_changed) ++ /* Check the next feature only if there is no error. */ ++ if (msg == NULL ++ && (info->feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0 ++ && (info->feature_1_legacy ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0) ++ { ++ if (info->enable_shstk_type != cet_permissive) + { +- unsigned int feature_1 = 0; +- if (enable_ibt) +- feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT; +- if (enable_shstk) +- feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; +- struct pthread *self = THREAD_SELF; +- THREAD_SETMEM (self, header.feature_1, feature_1); ++ legacy_obj = info->feature_1_legacy_shstk; ++ msg = N_("rebuild shared object with SHSTK support enabled"); + } ++ else ++ disable_feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ } ++ ++ /* If there is an error, long jump back to the caller. */ ++ if (msg != NULL) ++ _dl_signal_error (0, m->l_initfini[legacy_obj]->l_name, "dlopen", ++ msg); ++ ++ if (disable_feature_1 != 0) ++ { ++ int res = dl_cet_disable_cet (disable_feature_1); ++ if (res) ++ { ++ if ((disable_feature_1 ++ & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0) ++ msg = N_("can't disable IBT"); ++ else ++ msg = N_("can't disable SHSTK"); ++ /* Long jump back to the caller on error. */ ++ _dl_signal_error (-res, m->l_initfini[legacy_obj]->l_name, ++ "dlopen", msg); ++ } ++ ++ /* Clear the disabled bits in dl_x86_feature_1. */ ++ GL(dl_x86_feature_1) &= ~disable_feature_1; ++ ++ THREAD_SETMEM (THREAD_SELF, header.feature_1, ++ GL(dl_x86_feature_1)); ++ } ++} ++ ++static void ++dl_cet_check (struct link_map *m, const char *program) ++{ ++ struct dl_cet_info info; ++ ++ /* Check how IBT and SHSTK should be enabled. */ ++ info.enable_ibt_type = GL(dl_x86_feature_control).ibt; ++ info.enable_shstk_type = GL(dl_x86_feature_control).shstk; ++ ++ info.feature_1_enabled = GL(dl_x86_feature_1); ++ ++ /* No legacy object check if IBT and SHSTK are always on. */ ++ if (info.enable_ibt_type == cet_always_on ++ && info.enable_shstk_type == cet_always_on) ++ { ++#ifdef SHARED ++ /* Set it only during startup. */ ++ if (program != NULL) ++ THREAD_SETMEM (THREAD_SELF, header.feature_1, ++ info.feature_1_enabled); ++#endif ++ return; + } ++ ++ /* Check if IBT and SHSTK were enabled by kernel. */ ++ if (info.feature_1_enabled == 0) ++ return; ++ ++ info.program = program; ++ ++ /* Check which features should be enabled. */ ++ info.enable_feature_1 = 0; ++ if (info.enable_ibt_type != cet_always_off) ++ info.enable_feature_1 |= (info.feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_IBT); ++ if (info.enable_shstk_type != cet_always_off) ++ info.enable_feature_1 |= (info.feature_1_enabled ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK); ++ ++ /* Start with no legacy objects. */ ++ info.feature_1_legacy = 0; ++ info.feature_1_legacy_ibt = 0; ++ info.feature_1_legacy_shstk = 0; ++ ++#ifdef SHARED ++ if (program) ++ dl_cet_check_startup (m, &info); ++ else ++#endif ++ dl_cet_check_dlopen (m, &info); + } + + void +-- +2.27.0 + diff --git a/x86-Move-CET-infrastructure-to-x86_64.patch b/x86-Move-CET-infrastructure-to-x86_64.patch new file mode 100644 index 0000000..34b3c13 --- /dev/null +++ b/x86-Move-CET-infrastructure-to-x86_64.patch @@ -0,0 +1,950 @@ +From 1e739f0a04523d2c4b3a4dcb99987593c7ec2958 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 5 Jan 2024 09:32:37 -0300 +Subject: [PATCH] x86: Move CET infrastructure to x86_64 + +The CET is only supported for x86_64 and there is no plan to add +kernel support for i386. Move the Makefile rules and files from the +generic x86 folder to x86_64 one. + +Checked on x86_64-linux-gnu and i686-linux-gnu. + +(cherry picked from commit b7fc4a07f206a640e6d807d72f5c1ee3ea7a25b6) +--- + sysdeps/unix/sysv/linux/x86/Makefile | 27 -- + sysdeps/unix/sysv/linux/x86_64/Makefile | 27 ++ + .../linux/{x86 => x86_64}/include/asm/prctl.h | 0 + .../{x86 => x86_64}/tst-cet-property-1.c | 0 + .../{x86 => x86_64}/tst-cet-property-2.c | 0 + .../{x86 => x86_64}/tst-cet-property-dep-2.S | 0 + .../{x86 => x86_64}/tst-cet-setcontext-1.c | 0 + .../linux/{x86 => x86_64}/tst-cet-vfork-1.c | 0 + sysdeps/x86/Makefile | 238 ----------------- + sysdeps/x86_64/Makefile | 243 ++++++++++++++++++ + sysdeps/{x86 => x86_64}/tst-cet-legacy-1.c | 0 + .../tst-cet-legacy-10-static.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-10.c | 0 + .../tst-cet-legacy-10a-static.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-10a.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-1a.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-2.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-2a.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-3.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-4.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-4a.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-4b.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-4c.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-5.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-5a.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-5b.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-6.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-6a.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-6b.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-7.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-8.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-9-static.c | 0 + sysdeps/{x86 => x86_64}/tst-cet-legacy-9.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-1.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-2.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-4.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-5.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-5a.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-5b.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-5c.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-6.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-6a.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-6b.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-6c.c | 0 + .../{x86 => x86_64}/tst-cet-legacy-mod-6d.c | 0 + .../tst-shstk-legacy-1-extra.S | 0 + .../tst-shstk-legacy-1a-static.c | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1a.c | 0 + .../tst-shstk-legacy-1b-static.c | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1b.c | 0 + .../tst-shstk-legacy-1c-static.c | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1c.c | 0 + .../tst-shstk-legacy-1d-static.c | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1d.c | 0 + .../tst-shstk-legacy-1e-static.c | 0 + .../tst-shstk-legacy-1e-static.sh | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1e.c | 0 + .../{x86 => x86_64}/tst-shstk-legacy-1e.sh | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1f.c | 0 + sysdeps/{x86 => x86_64}/tst-shstk-legacy-1g.c | 0 + .../{x86 => x86_64}/tst-shstk-legacy-1g.sh | 0 + .../{x86 => x86_64}/tst-shstk-legacy-mod-1.c | 0 + 62 files changed, 270 insertions(+), 265 deletions(-) + rename sysdeps/unix/sysv/linux/{x86 => x86_64}/include/asm/prctl.h (100%) + rename sysdeps/unix/sysv/linux/{x86 => x86_64}/tst-cet-property-1.c (100%) + rename sysdeps/unix/sysv/linux/{x86 => x86_64}/tst-cet-property-2.c (100%) + rename sysdeps/unix/sysv/linux/{x86 => x86_64}/tst-cet-property-dep-2.S (100%) + rename sysdeps/unix/sysv/linux/{x86 => x86_64}/tst-cet-setcontext-1.c (100%) + rename sysdeps/unix/sysv/linux/{x86 => x86_64}/tst-cet-vfork-1.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-1.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-10-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-10.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-10a-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-10a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-1a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-2.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-2a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-3.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-4.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-4a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-4b.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-4c.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-5.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-5a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-5b.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-6.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-6a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-6b.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-7.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-8.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-9-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-9.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-1.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-2.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-4.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-5.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-5a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-5b.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-5c.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-6.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-6a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-6b.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-6c.c (100%) + rename sysdeps/{x86 => x86_64}/tst-cet-legacy-mod-6d.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1-extra.S (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1a-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1a.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1b-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1b.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1c-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1c.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1d-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1d.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1e-static.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1e-static.sh (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1e.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1e.sh (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1f.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1g.c (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-1g.sh (100%) + rename sysdeps/{x86 => x86_64}/tst-shstk-legacy-mod-1.c (100%) + +diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile +index 9dfdd689a9..743b633b65 100644 +--- a/sysdeps/unix/sysv/linux/x86/Makefile ++++ b/sysdeps/unix/sysv/linux/x86/Makefile +@@ -21,30 +21,3 @@ endif + ifeq ($(subdir),setjmp) + tests += tst-saved_mask-1 + endif +- +-ifneq ($(enable-cet),no) +-ifeq ($(subdir),elf) +-tests += tst-cet-property-1 tst-cet-property-2 +- +-CFLAGS-tst-cet-property-1.o += -fcf-protection +-ASFLAGS-tst-cet-property-dep-2.o += -fcf-protection +- +-$(objpfx)tst-cet-property-2: $(objpfx)tst-cet-property-dep-2.o +-$(objpfx)tst-cet-property-2.out: $(objpfx)tst-cet-property-2 \ +- $(objpfx)tst-cet-property-1.out +- env $(run-program-env) $(test-via-rtld-prefix) \ +- $(objpfx)tst-cet-property-2 \ +- < $(objpfx)tst-cet-property-1.out > $@; \ +- $(evaluate-test) +-endif +- +-ifeq ($(subdir),posix) +-tests += tst-cet-vfork-1 +-CFLAGS-tst-cet-vfork-1.c += -mshstk +-endif +- +-ifeq ($(subdir),stdlib) +-tests += tst-cet-setcontext-1 +-CFLAGS-tst-cet-setcontext-1.c += -mshstk +-endif +-endif +diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile +index 06b873949e..4223feb95f 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/Makefile ++++ b/sysdeps/unix/sysv/linux/x86_64/Makefile +@@ -64,3 +64,30 @@ $(objpfx)libx86-64-isa-level.so: $(objpfx)libx86-64-isa-level-1.so + cp $< $@ + endif + endif # $(subdir) == elf ++ ++ifneq ($(enable-cet),no) ++ifeq ($(subdir),elf) ++tests += tst-cet-property-1 tst-cet-property-2 ++ ++CFLAGS-tst-cet-property-1.o += -fcf-protection ++ASFLAGS-tst-cet-property-dep-2.o += -fcf-protection ++ ++$(objpfx)tst-cet-property-2: $(objpfx)tst-cet-property-dep-2.o ++$(objpfx)tst-cet-property-2.out: $(objpfx)tst-cet-property-2 \ ++ $(objpfx)tst-cet-property-1.out ++ env $(run-program-env) $(test-via-rtld-prefix) \ ++ $(objpfx)tst-cet-property-2 \ ++ < $(objpfx)tst-cet-property-1.out > $@; \ ++ $(evaluate-test) ++endif ++ ++ifeq ($(subdir),posix) ++tests += tst-cet-vfork-1 ++CFLAGS-tst-cet-vfork-1.c += -mshstk ++endif ++ ++ifeq ($(subdir),stdlib) ++tests += tst-cet-setcontext-1 ++CFLAGS-tst-cet-setcontext-1.c += -mshstk ++endif ++endif +diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h +similarity index 100% +rename from sysdeps/unix/sysv/linux/x86/include/asm/prctl.h +rename to sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-property-1.c b/sysdeps/unix/sysv/linux/x86_64/tst-cet-property-1.c +similarity index 100% +rename from sysdeps/unix/sysv/linux/x86/tst-cet-property-1.c +rename to sysdeps/unix/sysv/linux/x86_64/tst-cet-property-1.c +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-property-2.c b/sysdeps/unix/sysv/linux/x86_64/tst-cet-property-2.c +similarity index 100% +rename from sysdeps/unix/sysv/linux/x86/tst-cet-property-2.c +rename to sysdeps/unix/sysv/linux/x86_64/tst-cet-property-2.c +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-property-dep-2.S b/sysdeps/unix/sysv/linux/x86_64/tst-cet-property-dep-2.S +similarity index 100% +rename from sysdeps/unix/sysv/linux/x86/tst-cet-property-dep-2.S +rename to sysdeps/unix/sysv/linux/x86_64/tst-cet-property-dep-2.S +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c b/sysdeps/unix/sysv/linux/x86_64/tst-cet-setcontext-1.c +similarity index 100% +rename from sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c +rename to sysdeps/unix/sysv/linux/x86_64/tst-cet-setcontext-1.c +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c b/sysdeps/unix/sysv/linux/x86_64/tst-cet-vfork-1.c +similarity index 100% +rename from sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c +rename to sysdeps/unix/sysv/linux/x86_64/tst-cet-vfork-1.c +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 2bd7e358e5..4f8fcc8e1b 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -91,12 +91,6 @@ endif # $(subdir) == math + ifeq ($(subdir),setjmp) + gen-as-const-headers += jmp_buf-ssp.sym + sysdep_routines += __longjmp_cancel +-ifneq ($(enable-cet),no) +-tests += \ +- tst-setjmp-cet \ +-# tests +-tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on +-endif + endif + + ifeq ($(subdir),string) +@@ -137,238 +131,6 @@ CFLAGS-tst-wcscmp-rtm.c += -mrtm + CFLAGS-tst-wcsncmp-rtm.c += -mrtm -Wno-error + endif + +-ifneq ($(enable-cet),no) +-ifeq ($(subdir),elf) +-sysdep-dl-routines += dl-cet +- +-tests += \ +- tst-cet-legacy-1 \ +- tst-cet-legacy-1a \ +- tst-cet-legacy-2 \ +- tst-cet-legacy-2a \ +- tst-cet-legacy-3 \ +- tst-cet-legacy-4 \ +- tst-cet-legacy-5a \ +- tst-cet-legacy-6a \ +- tst-cet-legacy-7 \ +- tst-cet-legacy-8 \ +- tst-cet-legacy-9 \ +- tst-cet-legacy-9-static \ +- tst-cet-legacy-10 \ +- tst-cet-legacy-10-static \ +- tst-cet-legacy-10a \ +- tst-cet-legacy-10a-static \ +-# tests +-tests-static += \ +- tst-cet-legacy-9-static \ +- tst-cet-legacy-10-static \ +- tst-cet-legacy-10a-static \ +-# tests-static +-tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd) +- +-tests += \ +- tst-shstk-legacy-1a \ +- tst-shstk-legacy-1a-static \ +- tst-shstk-legacy-1b \ +- tst-shstk-legacy-1b-static \ +- tst-shstk-legacy-1c \ +- tst-shstk-legacy-1c-static \ +- tst-shstk-legacy-1d \ +- tst-shstk-legacy-1d-static \ +- tst-shstk-legacy-1e \ +- tst-shstk-legacy-1e-static \ +- tst-shstk-legacy-1f \ +- tst-shstk-legacy-1g \ +-# tests +-modules-names += \ +- tst-shstk-legacy-mod-1 \ +-# modules-names +-tests-static += \ +- tst-shstk-legacy-1a-static \ +- tst-shstk-legacy-1b-static \ +- tst-shstk-legacy-1c-static \ +- tst-shstk-legacy-1d-static \ +- tst-shstk-legacy-1e-static \ +-# tests-static +-extra-objs += \ +- tst-shstk-legacy-1-extra.o \ +-# extra-objs +- +-tests += \ +- tst-cet-legacy-4a \ +- tst-cet-legacy-4b \ +- tst-cet-legacy-4c \ +- tst-cet-legacy-5b \ +- tst-cet-legacy-6b \ +-# tests +-modules-names += \ +- tst-cet-legacy-mod-1 \ +- tst-cet-legacy-mod-2 \ +- tst-cet-legacy-mod-4 \ +- tst-cet-legacy-mod-5a \ +- tst-cet-legacy-mod-5b \ +- tst-cet-legacy-mod-5c \ +- tst-cet-legacy-mod-6a \ +- tst-cet-legacy-mod-6b \ +- tst-cet-legacy-mod-6c \ +-# modules-names +- +-CFLAGS-tst-cet-legacy-2.c += -fcf-protection=none -fcf-protection=branch +-CFLAGS-tst-cet-legacy-2a.c += -fcf-protection +-CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-4.c += -fcf-protection=none -fcf-protection=branch +-CPPFLAGS-tst-cet-legacy-4a.c += -DCET_IS_PERMISSIVE=1 +-CFLAGS-tst-cet-legacy-4a.c += -fcf-protection +-CFLAGS-tst-cet-legacy-4b.c += -fcf-protection +-CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-5a.c += -fcf-protection -mshstk +-ifeq ($(enable-cet),permissive) +-CPPFLAGS-tst-cet-legacy-5a.c += -DCET_IS_PERMISSIVE=1 +-endif +-CFLAGS-tst-cet-legacy-5b.c += -fcf-protection -mshstk +-CPPFLAGS-tst-cet-legacy-5b.c += -DCET_DISABLED_BY_ENV=1 +-CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none -fcf-protection=branch +-CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection +-CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection +-CFLAGS-tst-cet-legacy-6a.c += -fcf-protection -mshstk +-ifeq ($(enable-cet),permissive) +-CPPFLAGS-tst-cet-legacy-6a.c += -DCET_IS_PERMISSIVE=1 +-endif +-CFLAGS-tst-cet-legacy-6b.c += -fcf-protection -mshstk +-CPPFLAGS-tst-cet-legacy-6b.c += -DCET_DISABLED_BY_ENV=1 +-CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none -fcf-protection=branch +-CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection +-CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection +-CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-10.c += -mshstk +-CFLAGS-tst-cet-legacy-10-static.c += -mshstk +-CFLAGS-tst-cet-legacy-10a.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-10a-static.c += -fcf-protection=none +- +-tst-cet-legacy-4-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-cet-legacy-6-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-cet-legacy-10-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-cet-legacy-10-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-cet-legacy-10a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-cet-legacy-10a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +- +-CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none +-CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none +-CFLAGS-tst-shstk-legacy-1d.c += -fcf-protection=none +-CFLAGS-tst-shstk-legacy-1d-static.c += -fcf-protection=none +-CFLAGS-tst-shstk-legacy-1f.c += -fcf-protection=none +- +-$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ +- $(objpfx)tst-cet-legacy-mod-2.so +-$(objpfx)tst-cet-legacy-1a: $(objpfx)tst-cet-legacy-mod-1.so \ +- $(objpfx)tst-cet-legacy-mod-2.so +-$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so +-$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so +-$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so +-$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so +-$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so +-$(objpfx)tst-cet-legacy-5a.out: $(objpfx)tst-cet-legacy-mod-5a.so \ +- $(objpfx)tst-cet-legacy-mod-5b.so +-$(objpfx)tst-cet-legacy-mod-5a.so: $(objpfx)tst-cet-legacy-mod-5c.so +-$(objpfx)tst-cet-legacy-mod-5b.so: $(objpfx)tst-cet-legacy-mod-5c.so +-$(objpfx)tst-cet-legacy-6a.out: $(objpfx)tst-cet-legacy-mod-6a.so \ +- $(objpfx)tst-cet-legacy-mod-6b.so +-$(objpfx)tst-cet-legacy-mod-6a.so: $(objpfx)tst-cet-legacy-mod-6c.so +-$(objpfx)tst-cet-legacy-mod-6b.so: $(objpfx)tst-cet-legacy-mod-6c.so +-LDFLAGS-tst-cet-legacy-mod-6c.so = -Wl,--enable-new-dtags,-z,nodelete +-$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so +-tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=permissive +-$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so +-tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=on +-$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so +-tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=off +-$(objpfx)tst-cet-legacy-5b.out: $(objpfx)tst-cet-legacy-mod-5a.so \ +- $(objpfx)tst-cet-legacy-mod-5b.so +-tst-cet-legacy-5b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK +-$(objpfx)tst-cet-legacy-6b.out: $(objpfx)tst-cet-legacy-mod-6a.so \ +- $(objpfx)tst-cet-legacy-mod-6b.so +-tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK +-tst-cet-legacy-9-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK +-tst-cet-legacy-9-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK +- +-tst-shstk-legacy-1a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-shstk-legacy-1a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-$(objpfx)tst-shstk-legacy-1a: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1a-static: $(objpfx)tst-shstk-legacy-1-extra.o +-tst-shstk-legacy-1b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-shstk-legacy-1b-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-$(objpfx)tst-shstk-legacy-1b: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1b-static: $(objpfx)tst-shstk-legacy-1-extra.o +-tst-shstk-legacy-1c-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK +-tst-shstk-legacy-1c-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK +-$(objpfx)tst-shstk-legacy-1c: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1c-static: $(objpfx)tst-shstk-legacy-1-extra.o +-tst-shstk-legacy-1d-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-tst-shstk-legacy-1d-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-$(objpfx)tst-shstk-legacy-1d: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1d-static: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1e: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1e-static: $(objpfx)tst-shstk-legacy-1-extra.o +-$(objpfx)tst-shstk-legacy-1e.out: \ +- $(..)/sysdeps/x86/tst-shstk-legacy-1e.sh $(objpfx)tst-shstk-legacy-1e +- $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \ +- $(evaluate-test) +-$(objpfx)tst-shstk-legacy-1e-static.out: \ +- $(..)/sysdeps/x86/tst-shstk-legacy-1e-static.sh \ +- $(objpfx)tst-shstk-legacy-1e-static +- $(SHELL) $< $(common-objpfx) 2> $@; \ +- $(evaluate-test) +-tst-shstk-legacy-1f-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK +-$(objpfx)tst-shstk-legacy-1f: $(objpfx)tst-shstk-legacy-mod-1.so +-$(objpfx)tst-shstk-legacy-mod-1.so: \ +- $(objpfx)tst-shstk-legacy-mod-1.os \ +- $(objpfx)tst-shstk-legacy-1-extra.os +-$(objpfx)tst-shstk-legacy-1g: $(objpfx)tst-shstk-legacy-mod-1.so +-$(objpfx)tst-shstk-legacy-1g.out: \ +- $(..)/sysdeps/x86/tst-shstk-legacy-1g.sh $(objpfx)tst-shstk-legacy-1g +- $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \ +- $(evaluate-test) +-endif +- +-# Add -fcf-protection to CFLAGS when CET is enabled. +-CFLAGS-.o += -fcf-protection +-CFLAGS-.os += -fcf-protection +-CFLAGS-.op += -fcf-protection +-CFLAGS-.oS += -fcf-protection +- +-# Compile assembly codes with when CET is enabled. +-asm-CPPFLAGS += -fcf-protection -include cet.h +- +-ifeq ($(subdir),elf) +-ifeq (yes,$(build-shared)) +-tests-special += $(objpfx)check-cet.out +-endif +- +-# FIXME: Can't use all-built-dso in elf/Makefile since this file is +-# processed before elf/Makefile. Duplicate it here. +-cet-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \ +- $(filter-out $(common-objpfx)linkobj/libc.so, \ +- $(sort $(wildcard $(addprefix $(common-objpfx), \ +- */lib*.so \ +- iconvdata/*.so)))) +- +-$(cet-built-dso:=.note): %.note: % +- @rm -f $@T +- LC_ALL=C $(READELF) -n $< > $@T +- test -s $@T +- mv -f $@T $@ +-common-generated += $(cet-built-dso:$(common-objpfx)%=%.note) +- +-$(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \ +- $(cet-built-dso:=.note) +- LC_ALL=C $(AWK) -f $^ > $@; \ +- $(evaluate-test) +-generated += check-cet.out +-endif +-endif +- + ifeq ($(subdir),posix) + tests += \ + tst-sysconf-cache-linesize \ +diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile +index 105a9a431e..48182b437b 100644 +--- a/sysdeps/x86_64/Makefile ++++ b/sysdeps/x86_64/Makefile +@@ -207,6 +207,249 @@ tests += \ + tst-rsi-wcslen + endif + ++ ++ifeq ($(subdir),setjmp) ++ifneq ($(enable-cet),no) ++tests += \ ++ tst-setjmp-cet \ ++# tests ++tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on ++endif ++endif ++ ++ ++ifneq ($(enable-cet),no) ++ifeq ($(subdir),elf) ++sysdep-dl-routines += dl-cet ++ ++tests += \ ++ tst-cet-legacy-1 \ ++ tst-cet-legacy-1a \ ++ tst-cet-legacy-2 \ ++ tst-cet-legacy-2a \ ++ tst-cet-legacy-3 \ ++ tst-cet-legacy-4 \ ++ tst-cet-legacy-5a \ ++ tst-cet-legacy-6a \ ++ tst-cet-legacy-7 \ ++ tst-cet-legacy-8 \ ++ tst-cet-legacy-9 \ ++ tst-cet-legacy-9-static \ ++ tst-cet-legacy-10 \ ++ tst-cet-legacy-10-static \ ++ tst-cet-legacy-10a \ ++ tst-cet-legacy-10a-static \ ++# tests ++tests-static += \ ++ tst-cet-legacy-9-static \ ++ tst-cet-legacy-10-static \ ++ tst-cet-legacy-10a-static \ ++# tests-static ++tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd) ++ ++tests += \ ++ tst-shstk-legacy-1a \ ++ tst-shstk-legacy-1a-static \ ++ tst-shstk-legacy-1b \ ++ tst-shstk-legacy-1b-static \ ++ tst-shstk-legacy-1c \ ++ tst-shstk-legacy-1c-static \ ++ tst-shstk-legacy-1d \ ++ tst-shstk-legacy-1d-static \ ++ tst-shstk-legacy-1e \ ++ tst-shstk-legacy-1e-static \ ++ tst-shstk-legacy-1f \ ++ tst-shstk-legacy-1g \ ++# tests ++modules-names += \ ++ tst-shstk-legacy-mod-1 \ ++# modules-names ++tests-static += \ ++ tst-shstk-legacy-1a-static \ ++ tst-shstk-legacy-1b-static \ ++ tst-shstk-legacy-1c-static \ ++ tst-shstk-legacy-1d-static \ ++ tst-shstk-legacy-1e-static \ ++# tests-static ++extra-objs += \ ++ tst-shstk-legacy-1-extra.o \ ++# extra-objs ++ ++tests += \ ++ tst-cet-legacy-4a \ ++ tst-cet-legacy-4b \ ++ tst-cet-legacy-4c \ ++ tst-cet-legacy-5b \ ++ tst-cet-legacy-6b \ ++# tests ++modules-names += \ ++ tst-cet-legacy-mod-1 \ ++ tst-cet-legacy-mod-2 \ ++ tst-cet-legacy-mod-4 \ ++ tst-cet-legacy-mod-5a \ ++ tst-cet-legacy-mod-5b \ ++ tst-cet-legacy-mod-5c \ ++ tst-cet-legacy-mod-6a \ ++ tst-cet-legacy-mod-6b \ ++ tst-cet-legacy-mod-6c \ ++# modules-names ++ ++CFLAGS-tst-cet-legacy-2.c += -fcf-protection=none -fcf-protection=branch ++CFLAGS-tst-cet-legacy-2a.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-4.c += -fcf-protection=none -fcf-protection=branch ++CPPFLAGS-tst-cet-legacy-4a.c += -DCET_IS_PERMISSIVE=1 ++CFLAGS-tst-cet-legacy-4a.c += -fcf-protection ++CFLAGS-tst-cet-legacy-4b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-5a.c += -fcf-protection -mshstk ++ifeq ($(enable-cet),permissive) ++CPPFLAGS-tst-cet-legacy-5a.c += -DCET_IS_PERMISSIVE=1 ++endif ++CFLAGS-tst-cet-legacy-5b.c += -fcf-protection -mshstk ++CPPFLAGS-tst-cet-legacy-5b.c += -DCET_DISABLED_BY_ENV=1 ++CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none -fcf-protection=branch ++CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection ++CFLAGS-tst-cet-legacy-6a.c += -fcf-protection -mshstk ++ifeq ($(enable-cet),permissive) ++CPPFLAGS-tst-cet-legacy-6a.c += -DCET_IS_PERMISSIVE=1 ++endif ++CFLAGS-tst-cet-legacy-6b.c += -fcf-protection -mshstk ++CPPFLAGS-tst-cet-legacy-6b.c += -DCET_DISABLED_BY_ENV=1 ++CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none -fcf-protection=branch ++CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection ++CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-10.c += -mshstk ++CFLAGS-tst-cet-legacy-10-static.c += -mshstk ++CFLAGS-tst-cet-legacy-10a.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-10a-static.c += -fcf-protection=none ++ ++tst-cet-legacy-4-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-6-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++ ++CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1d.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1d-static.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1f.c += -fcf-protection=none ++ ++$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ ++ $(objpfx)tst-cet-legacy-mod-2.so ++$(objpfx)tst-cet-legacy-1a: $(objpfx)tst-cet-legacy-mod-1.so \ ++ $(objpfx)tst-cet-legacy-mod-2.so ++$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so ++$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so ++$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so ++$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so ++$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so ++$(objpfx)tst-cet-legacy-5a.out: $(objpfx)tst-cet-legacy-mod-5a.so \ ++ $(objpfx)tst-cet-legacy-mod-5b.so ++$(objpfx)tst-cet-legacy-mod-5a.so: $(objpfx)tst-cet-legacy-mod-5c.so ++$(objpfx)tst-cet-legacy-mod-5b.so: $(objpfx)tst-cet-legacy-mod-5c.so ++$(objpfx)tst-cet-legacy-6a.out: $(objpfx)tst-cet-legacy-mod-6a.so \ ++ $(objpfx)tst-cet-legacy-mod-6b.so ++$(objpfx)tst-cet-legacy-mod-6a.so: $(objpfx)tst-cet-legacy-mod-6c.so ++$(objpfx)tst-cet-legacy-mod-6b.so: $(objpfx)tst-cet-legacy-mod-6c.so ++LDFLAGS-tst-cet-legacy-mod-6c.so = -Wl,--enable-new-dtags,-z,nodelete ++$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so ++tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=permissive ++$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so ++tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=on ++$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so ++tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=off ++$(objpfx)tst-cet-legacy-5b.out: $(objpfx)tst-cet-legacy-mod-5a.so \ ++ $(objpfx)tst-cet-legacy-mod-5b.so ++tst-cet-legacy-5b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK ++$(objpfx)tst-cet-legacy-6b.out: $(objpfx)tst-cet-legacy-mod-6a.so \ ++ $(objpfx)tst-cet-legacy-mod-6b.so ++tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK ++tst-cet-legacy-9-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK ++tst-cet-legacy-9-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK ++ ++tst-shstk-legacy-1a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-shstk-legacy-1a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++$(objpfx)tst-shstk-legacy-1a: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1a-static: $(objpfx)tst-shstk-legacy-1-extra.o ++tst-shstk-legacy-1b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-shstk-legacy-1b-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++$(objpfx)tst-shstk-legacy-1b: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1b-static: $(objpfx)tst-shstk-legacy-1-extra.o ++tst-shstk-legacy-1c-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK ++tst-shstk-legacy-1c-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK ++$(objpfx)tst-shstk-legacy-1c: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1c-static: $(objpfx)tst-shstk-legacy-1-extra.o ++tst-shstk-legacy-1d-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-shstk-legacy-1d-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++$(objpfx)tst-shstk-legacy-1d: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1d-static: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1e: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1e-static: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1e.out: \ ++ $(..)/sysdeps/x86_64/tst-shstk-legacy-1e.sh $(objpfx)tst-shstk-legacy-1e ++ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \ ++ $(evaluate-test) ++$(objpfx)tst-shstk-legacy-1e-static.out: \ ++ $(..)/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh \ ++ $(objpfx)tst-shstk-legacy-1e-static ++ $(SHELL) $< $(common-objpfx) 2> $@; \ ++ $(evaluate-test) ++tst-shstk-legacy-1f-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++$(objpfx)tst-shstk-legacy-1f: $(objpfx)tst-shstk-legacy-mod-1.so ++$(objpfx)tst-shstk-legacy-mod-1.so: \ ++ $(objpfx)tst-shstk-legacy-mod-1.os \ ++ $(objpfx)tst-shstk-legacy-1-extra.os ++$(objpfx)tst-shstk-legacy-1g: $(objpfx)tst-shstk-legacy-mod-1.so ++$(objpfx)tst-shstk-legacy-1g.out: \ ++ $(..)/sysdeps/x86_64/tst-shstk-legacy-1g.sh $(objpfx)tst-shstk-legacy-1g ++ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \ ++ $(evaluate-test) ++endif ++ ++# Add -fcf-protection to CFLAGS when CET is enabled. ++CFLAGS-.o += -fcf-protection ++CFLAGS-.os += -fcf-protection ++CFLAGS-.op += -fcf-protection ++CFLAGS-.oS += -fcf-protection ++ ++# Compile assembly codes with when CET is enabled. ++asm-CPPFLAGS += -fcf-protection -include cet.h ++ ++ifeq ($(subdir),elf) ++ifeq (yes,$(build-shared)) ++tests-special += $(objpfx)check-cet.out ++endif ++ ++# FIXME: Can't use all-built-dso in elf/Makefile since this file is ++# processed before elf/Makefile. Duplicate it here. ++cet-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \ ++ $(filter-out $(common-objpfx)linkobj/libc.so, \ ++ $(sort $(wildcard $(addprefix $(common-objpfx), \ ++ */lib*.so \ ++ iconvdata/*.so)))) ++ ++$(cet-built-dso:=.note): %.note: % ++ @rm -f $@T ++ LC_ALL=C $(READELF) -n $< > $@T ++ test -s $@T ++ mv -f $@T $@ ++common-generated += $(cet-built-dso:$(common-objpfx)%=%.note) ++ ++$(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \ ++ $(cet-built-dso:=.note) ++ LC_ALL=C $(AWK) -f $^ > $@; \ ++ $(evaluate-test) ++generated += check-cet.out ++endif # $(subdir) == elf ++endif # $(enable) != no ++ + do-tests-clean common-mostlyclean: tst-x86_64-1-clean + + .PHONY: tst-x86_64-1-clean +diff --git a/sysdeps/x86/tst-cet-legacy-1.c b/sysdeps/x86_64/tst-cet-legacy-1.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-1.c +rename to sysdeps/x86_64/tst-cet-legacy-1.c +diff --git a/sysdeps/x86/tst-cet-legacy-10-static.c b/sysdeps/x86_64/tst-cet-legacy-10-static.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-10-static.c +rename to sysdeps/x86_64/tst-cet-legacy-10-static.c +diff --git a/sysdeps/x86/tst-cet-legacy-10.c b/sysdeps/x86_64/tst-cet-legacy-10.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-10.c +rename to sysdeps/x86_64/tst-cet-legacy-10.c +diff --git a/sysdeps/x86/tst-cet-legacy-10a-static.c b/sysdeps/x86_64/tst-cet-legacy-10a-static.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-10a-static.c +rename to sysdeps/x86_64/tst-cet-legacy-10a-static.c +diff --git a/sysdeps/x86/tst-cet-legacy-10a.c b/sysdeps/x86_64/tst-cet-legacy-10a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-10a.c +rename to sysdeps/x86_64/tst-cet-legacy-10a.c +diff --git a/sysdeps/x86/tst-cet-legacy-1a.c b/sysdeps/x86_64/tst-cet-legacy-1a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-1a.c +rename to sysdeps/x86_64/tst-cet-legacy-1a.c +diff --git a/sysdeps/x86/tst-cet-legacy-2.c b/sysdeps/x86_64/tst-cet-legacy-2.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-2.c +rename to sysdeps/x86_64/tst-cet-legacy-2.c +diff --git a/sysdeps/x86/tst-cet-legacy-2a.c b/sysdeps/x86_64/tst-cet-legacy-2a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-2a.c +rename to sysdeps/x86_64/tst-cet-legacy-2a.c +diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86_64/tst-cet-legacy-3.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-3.c +rename to sysdeps/x86_64/tst-cet-legacy-3.c +diff --git a/sysdeps/x86/tst-cet-legacy-4.c b/sysdeps/x86_64/tst-cet-legacy-4.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-4.c +rename to sysdeps/x86_64/tst-cet-legacy-4.c +diff --git a/sysdeps/x86/tst-cet-legacy-4a.c b/sysdeps/x86_64/tst-cet-legacy-4a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-4a.c +rename to sysdeps/x86_64/tst-cet-legacy-4a.c +diff --git a/sysdeps/x86/tst-cet-legacy-4b.c b/sysdeps/x86_64/tst-cet-legacy-4b.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-4b.c +rename to sysdeps/x86_64/tst-cet-legacy-4b.c +diff --git a/sysdeps/x86/tst-cet-legacy-4c.c b/sysdeps/x86_64/tst-cet-legacy-4c.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-4c.c +rename to sysdeps/x86_64/tst-cet-legacy-4c.c +diff --git a/sysdeps/x86/tst-cet-legacy-5.c b/sysdeps/x86_64/tst-cet-legacy-5.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-5.c +rename to sysdeps/x86_64/tst-cet-legacy-5.c +diff --git a/sysdeps/x86/tst-cet-legacy-5a.c b/sysdeps/x86_64/tst-cet-legacy-5a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-5a.c +rename to sysdeps/x86_64/tst-cet-legacy-5a.c +diff --git a/sysdeps/x86/tst-cet-legacy-5b.c b/sysdeps/x86_64/tst-cet-legacy-5b.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-5b.c +rename to sysdeps/x86_64/tst-cet-legacy-5b.c +diff --git a/sysdeps/x86/tst-cet-legacy-6.c b/sysdeps/x86_64/tst-cet-legacy-6.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-6.c +rename to sysdeps/x86_64/tst-cet-legacy-6.c +diff --git a/sysdeps/x86/tst-cet-legacy-6a.c b/sysdeps/x86_64/tst-cet-legacy-6a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-6a.c +rename to sysdeps/x86_64/tst-cet-legacy-6a.c +diff --git a/sysdeps/x86/tst-cet-legacy-6b.c b/sysdeps/x86_64/tst-cet-legacy-6b.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-6b.c +rename to sysdeps/x86_64/tst-cet-legacy-6b.c +diff --git a/sysdeps/x86/tst-cet-legacy-7.c b/sysdeps/x86_64/tst-cet-legacy-7.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-7.c +rename to sysdeps/x86_64/tst-cet-legacy-7.c +diff --git a/sysdeps/x86/tst-cet-legacy-8.c b/sysdeps/x86_64/tst-cet-legacy-8.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-8.c +rename to sysdeps/x86_64/tst-cet-legacy-8.c +diff --git a/sysdeps/x86/tst-cet-legacy-9-static.c b/sysdeps/x86_64/tst-cet-legacy-9-static.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-9-static.c +rename to sysdeps/x86_64/tst-cet-legacy-9-static.c +diff --git a/sysdeps/x86/tst-cet-legacy-9.c b/sysdeps/x86_64/tst-cet-legacy-9.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-9.c +rename to sysdeps/x86_64/tst-cet-legacy-9.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-1.c b/sysdeps/x86_64/tst-cet-legacy-mod-1.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-1.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-1.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-2.c b/sysdeps/x86_64/tst-cet-legacy-mod-2.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-2.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-2.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-4.c b/sysdeps/x86_64/tst-cet-legacy-mod-4.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-4.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-4.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5.c b/sysdeps/x86_64/tst-cet-legacy-mod-5.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-5.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-5.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5a.c b/sysdeps/x86_64/tst-cet-legacy-mod-5a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-5a.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-5a.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5b.c b/sysdeps/x86_64/tst-cet-legacy-mod-5b.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-5b.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-5b.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5c.c b/sysdeps/x86_64/tst-cet-legacy-mod-5c.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-5c.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-5c.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6.c b/sysdeps/x86_64/tst-cet-legacy-mod-6.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-6.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-6.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6a.c b/sysdeps/x86_64/tst-cet-legacy-mod-6a.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-6a.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-6a.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6b.c b/sysdeps/x86_64/tst-cet-legacy-mod-6b.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-6b.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-6b.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6c.c b/sysdeps/x86_64/tst-cet-legacy-mod-6c.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-6c.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-6c.c +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6d.c b/sysdeps/x86_64/tst-cet-legacy-mod-6d.c +similarity index 100% +rename from sysdeps/x86/tst-cet-legacy-mod-6d.c +rename to sysdeps/x86_64/tst-cet-legacy-mod-6d.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1-extra.S b/sysdeps/x86_64/tst-shstk-legacy-1-extra.S +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1-extra.S +rename to sysdeps/x86_64/tst-shstk-legacy-1-extra.S +diff --git a/sysdeps/x86/tst-shstk-legacy-1a-static.c b/sysdeps/x86_64/tst-shstk-legacy-1a-static.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1a-static.c +rename to sysdeps/x86_64/tst-shstk-legacy-1a-static.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1a.c b/sysdeps/x86_64/tst-shstk-legacy-1a.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1a.c +rename to sysdeps/x86_64/tst-shstk-legacy-1a.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1b-static.c b/sysdeps/x86_64/tst-shstk-legacy-1b-static.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1b-static.c +rename to sysdeps/x86_64/tst-shstk-legacy-1b-static.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1b.c b/sysdeps/x86_64/tst-shstk-legacy-1b.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1b.c +rename to sysdeps/x86_64/tst-shstk-legacy-1b.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1c-static.c b/sysdeps/x86_64/tst-shstk-legacy-1c-static.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1c-static.c +rename to sysdeps/x86_64/tst-shstk-legacy-1c-static.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1c.c b/sysdeps/x86_64/tst-shstk-legacy-1c.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1c.c +rename to sysdeps/x86_64/tst-shstk-legacy-1c.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1d-static.c b/sysdeps/x86_64/tst-shstk-legacy-1d-static.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1d-static.c +rename to sysdeps/x86_64/tst-shstk-legacy-1d-static.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1d.c b/sysdeps/x86_64/tst-shstk-legacy-1d.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1d.c +rename to sysdeps/x86_64/tst-shstk-legacy-1d.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1e-static.c b/sysdeps/x86_64/tst-shstk-legacy-1e-static.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1e-static.c +rename to sysdeps/x86_64/tst-shstk-legacy-1e-static.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1e-static.sh b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1e-static.sh +rename to sysdeps/x86_64/tst-shstk-legacy-1e-static.sh +diff --git a/sysdeps/x86/tst-shstk-legacy-1e.c b/sysdeps/x86_64/tst-shstk-legacy-1e.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1e.c +rename to sysdeps/x86_64/tst-shstk-legacy-1e.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1e.sh b/sysdeps/x86_64/tst-shstk-legacy-1e.sh +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1e.sh +rename to sysdeps/x86_64/tst-shstk-legacy-1e.sh +diff --git a/sysdeps/x86/tst-shstk-legacy-1f.c b/sysdeps/x86_64/tst-shstk-legacy-1f.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1f.c +rename to sysdeps/x86_64/tst-shstk-legacy-1f.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1g.c b/sysdeps/x86_64/tst-shstk-legacy-1g.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1g.c +rename to sysdeps/x86_64/tst-shstk-legacy-1g.c +diff --git a/sysdeps/x86/tst-shstk-legacy-1g.sh b/sysdeps/x86_64/tst-shstk-legacy-1g.sh +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-1g.sh +rename to sysdeps/x86_64/tst-shstk-legacy-1g.sh +diff --git a/sysdeps/x86/tst-shstk-legacy-mod-1.c b/sysdeps/x86_64/tst-shstk-legacy-mod-1.c +similarity index 100% +rename from sysdeps/x86/tst-shstk-legacy-mod-1.c +rename to sysdeps/x86_64/tst-shstk-legacy-mod-1.c +-- +2.27.0 + diff --git a/x86-Update-_dl_tlsdesc_dynamic-to-preserve-caller-sa.patch b/x86-Update-_dl_tlsdesc_dynamic-to-preserve-caller-sa.patch new file mode 100644 index 0000000..5410a1d --- /dev/null +++ b/x86-Update-_dl_tlsdesc_dynamic-to-preserve-caller-sa.patch @@ -0,0 +1,1469 @@ +From 88866d885c7acd2b74e4f78a35fbd7ac251ebc1f Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 26 Feb 2024 06:37:03 -0800 +Subject: [PATCH] x86: Update _dl_tlsdesc_dynamic to preserve + caller-saved registers + +Compiler generates the following instruction sequence for GNU2 dynamic +TLS access: + + leaq tls_var@TLSDESC(%rip), %rax + call *tls_var@TLSCALL(%rax) + +or + + leal tls_var@TLSDESC(%ebx), %eax + call *tls_var@TLSCALL(%eax) + +CALL instruction is transparent to compiler which assumes all registers, +except for EFLAGS and RAX/EAX, are unchanged after CALL. When +_dl_tlsdesc_dynamic is called, it calls __tls_get_addr on the slow +path. __tls_get_addr is a normal function which doesn't preserve any +caller-saved registers. _dl_tlsdesc_dynamic saved and restored integer +caller-saved registers, but didn't preserve any other caller-saved +registers. Add _dl_tlsdesc_dynamic IFUNC functions for FNSAVE, FXSAVE, +XSAVE and XSAVEC to save and restore all caller-saved registers. This +fixes BZ #31372. + +Add GLRO(dl_x86_64_runtime_resolve) with GLRO(dl_x86_tlsdesc_dynamic) +to optimize elf_machine_runtime_setup. +Reviewed-by: Noah Goldstein + +(cherry picked from commit 0aac205a814a8511e98d02b91a8dc908f1c53cde) +--- + elf/Makefile | 18 ++ + elf/tst-gnu2-tls2.c | 122 ++++++++++++ + elf/tst-gnu2-tls2.h | 36 ++++ + elf/tst-gnu2-tls2mod0.c | 31 +++ + elf/tst-gnu2-tls2mod1.c | 31 +++ + elf/tst-gnu2-tls2mod2.c | 31 +++ + sysdeps/i386/dl-machine.h | 2 +- + sysdeps/i386/dl-tlsdesc-dynamic.h | 190 +++++++++++++++++++ + sysdeps/i386/dl-tlsdesc.S | 115 +++++------ + sysdeps/x86/Makefile | 7 +- + sysdeps/x86/cpu-features.c | 54 ++++++ + sysdeps/x86/dl-procinfo.c | 16 ++ + sysdeps/{x86_64 => x86}/features-offsets.sym | 2 + + sysdeps/x86/sysdep.h | 6 + + sysdeps/x86/tst-gnu2-tls2.c | 20 ++ + sysdeps/x86_64/Makefile | 2 +- + sysdeps/x86_64/dl-machine.h | 16 +- + sysdeps/x86_64/dl-procinfo.c | 16 ++ + sysdeps/x86_64/dl-tlsdesc-dynamic.h | 166 ++++++++++++++++ + sysdeps/x86_64/dl-tlsdesc.S | 108 ++++------- + sysdeps/x86_64/dl-trampoline-save.h | 34 ++++ + sysdeps/x86_64/dl-trampoline-state.h | 51 +++++ + sysdeps/x86_64/dl-trampoline.S | 20 +- + sysdeps/x86_64/dl-trampoline.h | 34 +--- + 24 files changed, 919 insertions(+), 209 deletions(-) + create mode 100644 elf/tst-gnu2-tls2.c + create mode 100644 elf/tst-gnu2-tls2.h + create mode 100644 elf/tst-gnu2-tls2mod0.c + create mode 100644 elf/tst-gnu2-tls2mod1.c + create mode 100644 elf/tst-gnu2-tls2mod2.c + create mode 100644 sysdeps/i386/dl-tlsdesc-dynamic.h + rename sysdeps/{x86_64 => x86}/features-offsets.sym (89%) + create mode 100644 sysdeps/x86/tst-gnu2-tls2.c + create mode 100644 sysdeps/x86_64/dl-tlsdesc-dynamic.h + create mode 100644 sysdeps/x86_64/dl-trampoline-save.h + create mode 100644 sysdeps/x86_64/dl-trampoline-state.h + +diff --git a/elf/Makefile b/elf/Makefile +index 098d9a15b7..970192bde4 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -419,6 +419,7 @@ tests += \ + tst-glibc-hwcaps-prepend \ + tst-global1 \ + tst-global2 \ ++ tst-gnu2-tls2 \ + tst-initfinilazyfail \ + tst-initorder \ + tst-initorder2 \ +@@ -846,6 +847,9 @@ modules-names += \ + tst-filterobj-flt \ + tst-finilazyfailmod \ + tst-globalmod2 \ ++ tst-gnu2-tls2mod0 \ ++ tst-gnu2-tls2mod1 \ ++ tst-gnu2-tls2mod2 \ + tst-initlazyfailmod \ + tst-initorder2a \ + tst-initorder2b \ +@@ -3046,10 +3050,24 @@ $(objpfx)tst-tlsgap.out: \ + $(objpfx)tst-tlsgap-mod0.so \ + $(objpfx)tst-tlsgap-mod1.so \ + $(objpfx)tst-tlsgap-mod2.so ++ ++$(objpfx)tst-gnu2-tls2: $(shared-thread-library) ++$(objpfx)tst-gnu2-tls2.out: \ ++ $(objpfx)tst-gnu2-tls2mod0.so \ ++ $(objpfx)tst-gnu2-tls2mod1.so \ ++ $(objpfx)tst-gnu2-tls2mod2.so ++ + ifeq (yes,$(have-mtls-dialect-gnu2)) ++# This test fails if dl_tlsdesc_dynamic doesn't preserve all caller-saved ++# registers. See https://sourceware.org/bugzilla/show_bug.cgi?id=31372 ++test-xfail-tst-gnu2-tls2 = yes ++ + CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 + CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 + CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 ++CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=gnu2 ++CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=gnu2 ++CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=gnu2 + endif + + $(objpfx)tst-recursive-tls: $(objpfx)tst-recursive-tlsmallocmod.so +diff --git a/elf/tst-gnu2-tls2.c b/elf/tst-gnu2-tls2.c +new file mode 100644 +index 0000000000..7ac04d7f33 +--- /dev/null ++++ b/elf/tst-gnu2-tls2.c +@@ -0,0 +1,122 @@ ++/* Test TLSDESC relocation. ++ Copyright (C) 2024 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 "tst-gnu2-tls2.h" ++ ++#ifndef IS_SUPPORTED ++# define IS_SUPPORTED() true ++#endif ++ ++/* An architecture can define it to clobber caller-saved registers in ++ malloc below to verify that the implicit TLSDESC call won't change ++ caller-saved registers. */ ++#ifndef PREPARE_MALLOC ++# define PREPARE_MALLOC() ++#endif ++ ++extern void * __libc_malloc (size_t); ++ ++size_t malloc_counter = 0; ++ ++void * ++malloc (size_t n) ++{ ++ PREPARE_MALLOC (); ++ malloc_counter++; ++ return __libc_malloc (n); ++} ++ ++static void *mod[3]; ++#ifndef MOD ++# define MOD(i) "tst-gnu2-tls2mod" #i ".so" ++#endif ++static const char *modname[3] = { MOD(0), MOD(1), MOD(2) }; ++#undef MOD ++ ++static void ++open_mod (int i) ++{ ++ mod[i] = xdlopen (modname[i], RTLD_LAZY); ++ printf ("open %s\n", modname[i]); ++} ++ ++static void ++close_mod (int i) ++{ ++ xdlclose (mod[i]); ++ mod[i] = NULL; ++ printf ("close %s\n", modname[i]); ++} ++ ++static void ++access_mod (int i, const char *sym) ++{ ++ struct tls var = { -1, -1, -1, -1 }; ++ struct tls *(*f) (struct tls *) = xdlsym (mod[i], sym); ++ /* Check that our malloc is called. */ ++ malloc_counter = 0; ++ struct tls *p = f (&var); ++ TEST_VERIFY (malloc_counter != 0); ++ printf ("access %s: %s() = %p\n", modname[i], sym, p); ++ TEST_VERIFY_EXIT (memcmp (p, &var, sizeof (var)) == 0); ++ ++(p->a); ++} ++ ++static void * ++start (void *arg) ++{ ++ /* The DTV generation is at the last dlopen of mod0 and the ++ entry for mod1 is NULL. */ ++ ++ open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */ ++ ++ /* Force the slow path in GNU2 TLS descriptor call. */ ++ access_mod (1, "apply_tls"); ++ ++ return arg; ++} ++ ++static int ++do_test (void) ++{ ++ if (!IS_SUPPORTED ()) ++ return EXIT_UNSUPPORTED; ++ ++ open_mod (0); ++ open_mod (1); ++ open_mod (2); ++ close_mod (0); ++ close_mod (1); /* Create modid gap at mod1. */ ++ open_mod (0); /* Reuse modid of mod0, bump generation count. */ ++ ++ /* Create a thread where DTV of mod1 is NULL. */ ++ pthread_t t = xpthread_create (NULL, start, NULL); ++ xpthread_join (t); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-gnu2-tls2.h b/elf/tst-gnu2-tls2.h +new file mode 100644 +index 0000000000..77964a57a3 +--- /dev/null ++++ b/elf/tst-gnu2-tls2.h +@@ -0,0 +1,36 @@ ++/* Test TLSDESC relocation. ++ Copyright (C) 2024 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 ++ ++struct tls ++{ ++ int64_t a, b, c, d; ++}; ++ ++extern struct tls *apply_tls (struct tls *); ++ ++/* An architecture can define them to verify that clobber caller-saved ++ registers aren't changed by the implicit TLSDESC call. */ ++#ifndef BEFORE_TLSDESC_CALL ++# define BEFORE_TLSDESC_CALL() ++#endif ++ ++#ifndef AFTER_TLSDESC_CALL ++# define AFTER_TLSDESC_CALL() ++#endif +diff --git a/elf/tst-gnu2-tls2mod0.c b/elf/tst-gnu2-tls2mod0.c +new file mode 100644 +index 0000000000..45556a0e17 +--- /dev/null ++++ b/elf/tst-gnu2-tls2mod0.c +@@ -0,0 +1,31 @@ ++/* DSO used by tst-gnu2-tls2. ++ Copyright (C) 2024 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 "tst-gnu2-tls2.h" ++ ++__thread struct tls tls_var0 __attribute__ ((visibility ("hidden"))); ++ ++struct tls * ++apply_tls (struct tls *p) ++{ ++ BEFORE_TLSDESC_CALL (); ++ tls_var0 = *p; ++ struct tls *ret = &tls_var0; ++ AFTER_TLSDESC_CALL (); ++ return ret; ++} +diff --git a/elf/tst-gnu2-tls2mod1.c b/elf/tst-gnu2-tls2mod1.c +new file mode 100644 +index 0000000000..e10b9dbc0a +--- /dev/null ++++ b/elf/tst-gnu2-tls2mod1.c +@@ -0,0 +1,31 @@ ++/* DSO used by tst-gnu2-tls2. ++ Copyright (C) 2024 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 "tst-gnu2-tls2.h" ++ ++__thread struct tls tls_var1[100] __attribute__ ((visibility ("hidden"))); ++ ++struct tls * ++apply_tls (struct tls *p) ++{ ++ BEFORE_TLSDESC_CALL (); ++ tls_var1[1] = *p; ++ struct tls *ret = &tls_var1[1]; ++ AFTER_TLSDESC_CALL (); ++ return ret; ++} +diff --git a/elf/tst-gnu2-tls2mod2.c b/elf/tst-gnu2-tls2mod2.c +new file mode 100644 +index 0000000000..141af51e55 +--- /dev/null ++++ b/elf/tst-gnu2-tls2mod2.c +@@ -0,0 +1,31 @@ ++/* DSO used by tst-gnu2-tls2. ++ Copyright (C) 2024 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 "tst-gnu2-tls2.h" ++ ++__thread struct tls tls_var2 __attribute__ ((visibility ("hidden"))); ++ ++struct tls * ++apply_tls (struct tls *p) ++{ ++ BEFORE_TLSDESC_CALL (); ++ tls_var2 = *p; ++ struct tls *ret = &tls_var2; ++ AFTER_TLSDESC_CALL (); ++ return ret; ++} +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index b21322adc8..a521129d1f 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -345,7 +345,7 @@ and creates an unsatisfiable circular dependency.\n", + { + td->arg = _dl_make_tlsdesc_dynamic + (sym_map, sym->st_value + (ElfW(Word))td->arg); +- td->entry = _dl_tlsdesc_dynamic; ++ td->entry = GLRO(dl_x86_tlsdesc_dynamic); + } + else + # endif +diff --git a/sysdeps/i386/dl-tlsdesc-dynamic.h b/sysdeps/i386/dl-tlsdesc-dynamic.h +new file mode 100644 +index 0000000000..3627028577 +--- /dev/null ++++ b/sysdeps/i386/dl-tlsdesc-dynamic.h +@@ -0,0 +1,190 @@ ++/* Thread-local storage handling in the ELF dynamic linker. i386 version. ++ Copyright (C) 2004-2024 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 ++ . */ ++ ++#undef REGISTER_SAVE_AREA ++ ++#if !defined USE_FNSAVE && (STATE_SAVE_ALIGNMENT % 16) != 0 ++# error STATE_SAVE_ALIGNMENT must be multiple of 16 ++#endif ++ ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++# ifdef USE_FNSAVE ++# error USE_FNSAVE shouldn't be defined ++# endif ++# ifdef USE_FXSAVE ++/* Use fxsave to save all registers. */ ++# define REGISTER_SAVE_AREA 512 ++# endif ++#else ++# ifdef USE_FNSAVE ++/* Use fnsave to save x87 FPU stack registers. */ ++# define REGISTER_SAVE_AREA 108 ++# else ++# ifndef USE_FXSAVE ++# error USE_FXSAVE must be defined ++# endif ++/* Use fxsave to save all registers. Add 12 bytes to align the stack ++ to 16 bytes. */ ++# define REGISTER_SAVE_AREA (512 + 12) ++# endif ++#endif ++ ++ .hidden _dl_tlsdesc_dynamic ++ .global _dl_tlsdesc_dynamic ++ .type _dl_tlsdesc_dynamic,@function ++ ++ /* This function is used for symbols that need dynamic TLS. ++ ++ %eax points to the TLS descriptor, such that 0(%eax) points to ++ _dl_tlsdesc_dynamic itself, and 4(%eax) points to a struct ++ tlsdesc_dynamic_arg object. It must return in %eax the offset ++ between the thread pointer and the object denoted by the ++ argument, without clobbering any registers. ++ ++ The assembly code that follows is a rendition of the following ++ C code, hand-optimized a little bit. ++ ++ptrdiff_t ++__attribute__ ((__regparm__ (1))) ++_dl_tlsdesc_dynamic (struct tlsdesc *tdp) ++{ ++ struct tlsdesc_dynamic_arg *td = tdp->arg; ++ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); ++ if (__builtin_expect (td->gen_count <= dtv[0].counter ++ && (dtv[td->tlsinfo.ti_module].pointer.val ++ != TLS_DTV_UNALLOCATED), ++ 1)) ++ return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset ++ - __thread_pointer; ++ ++ return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; ++} ++*/ ++ cfi_startproc ++ .align 16 ++_dl_tlsdesc_dynamic: ++ /* Like all TLS resolvers, preserve call-clobbered registers. ++ We need two scratch regs anyway. */ ++ subl $32, %esp ++ cfi_adjust_cfa_offset (32) ++ movl %ecx, 20(%esp) ++ movl %edx, 24(%esp) ++ movl TLSDESC_ARG(%eax), %eax ++ movl %gs:DTV_OFFSET, %edx ++ movl TLSDESC_GEN_COUNT(%eax), %ecx ++ cmpl (%edx), %ecx ++ ja 2f ++ movl TLSDESC_MODID(%eax), %ecx ++ movl (%edx,%ecx,8), %edx ++ cmpl $-1, %edx ++ je 2f ++ movl TLSDESC_MODOFF(%eax), %eax ++ addl %edx, %eax ++1: ++ movl 20(%esp), %ecx ++ subl %gs:0, %eax ++ movl 24(%esp), %edx ++ addl $32, %esp ++ cfi_adjust_cfa_offset (-32) ++ ret ++ .p2align 4,,7 ++2: ++ cfi_adjust_cfa_offset (32) ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++ movl %ebx, -28(%esp) ++ movl %esp, %ebx ++ cfi_def_cfa_register(%ebx) ++ and $-STATE_SAVE_ALIGNMENT, %esp ++#endif ++#ifdef REGISTER_SAVE_AREA ++ subl $REGISTER_SAVE_AREA, %esp ++# if !DL_RUNTIME_RESOLVE_REALIGN_STACK ++ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) ++# endif ++#else ++# if !DL_RUNTIME_RESOLVE_REALIGN_STACK ++# error DL_RUNTIME_RESOLVE_REALIGN_STACK must be true ++# endif ++ /* Allocate stack space of the required size to save the state. */ ++ LOAD_PIC_REG (cx) ++ subl RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET+_rtld_local_ro@GOTOFF(%ecx), %esp ++#endif ++#ifdef USE_FNSAVE ++ fnsave (%esp) ++#elif defined USE_FXSAVE ++ fxsave (%esp) ++#else ++ /* Save the argument for ___tls_get_addr in EAX. */ ++ movl %eax, %ecx ++ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ /* Clear the XSAVE Header. */ ++# ifdef USE_XSAVE ++ movl %edx, (512)(%esp) ++ movl %edx, (512 + 4 * 1)(%esp) ++ movl %edx, (512 + 4 * 2)(%esp) ++ movl %edx, (512 + 4 * 3)(%esp) ++# endif ++ movl %edx, (512 + 4 * 4)(%esp) ++ movl %edx, (512 + 4 * 5)(%esp) ++ movl %edx, (512 + 4 * 6)(%esp) ++ movl %edx, (512 + 4 * 7)(%esp) ++ movl %edx, (512 + 4 * 8)(%esp) ++ movl %edx, (512 + 4 * 9)(%esp) ++ movl %edx, (512 + 4 * 10)(%esp) ++ movl %edx, (512 + 4 * 11)(%esp) ++ movl %edx, (512 + 4 * 12)(%esp) ++ movl %edx, (512 + 4 * 13)(%esp) ++ movl %edx, (512 + 4 * 14)(%esp) ++ movl %edx, (512 + 4 * 15)(%esp) ++# ifdef USE_XSAVE ++ xsave (%esp) ++# else ++ xsavec (%esp) ++# endif ++ /* Restore the argument for ___tls_get_addr in EAX. */ ++ movl %ecx, %eax ++#endif ++ call HIDDEN_JUMPTARGET (___tls_get_addr) ++ /* Get register content back. */ ++#ifdef USE_FNSAVE ++ frstor (%esp) ++#elif defined USE_FXSAVE ++ fxrstor (%esp) ++#else ++ /* Save and retore ___tls_get_addr return value stored in EAX. */ ++ movl %eax, %ecx ++ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ xrstor (%esp) ++ movl %ecx, %eax ++#endif ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++ mov %ebx, %esp ++ cfi_def_cfa_register(%esp) ++ movl -28(%esp), %ebx ++ cfi_restore(%ebx) ++#else ++ addl $REGISTER_SAVE_AREA, %esp ++ cfi_adjust_cfa_offset(-REGISTER_SAVE_AREA) ++#endif ++ jmp 1b ++ cfi_endproc ++ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic ++ ++#undef STATE_SAVE_ALIGNMENT +diff --git a/sysdeps/i386/dl-tlsdesc.S b/sysdeps/i386/dl-tlsdesc.S +index 0574ce714e..725506f58d 100644 +--- a/sysdeps/i386/dl-tlsdesc.S ++++ b/sysdeps/i386/dl-tlsdesc.S +@@ -18,8 +18,27 @@ + + #include + #include ++#include ++#include + #include "tlsdesc.h" + ++#ifndef DL_STACK_ALIGNMENT ++/* Due to GCC bug: ++ ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 ++ ++ __tls_get_addr may be called with 4-byte stack alignment. Although ++ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume ++ that stack will be always aligned at 16 bytes. */ ++# define DL_STACK_ALIGNMENT 4 ++#endif ++ ++/* True if _dl_tlsdesc_dynamic should align stack for STATE_SAVE or align ++ stack to MINIMUM_ALIGNMENT bytes before calling ___tls_get_addr. */ ++#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ ++ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ ++ || MINIMUM_ALIGNMENT > DL_STACK_ALIGNMENT) ++ + .text + + /* This function is used to compute the TP offset for symbols in +@@ -65,69 +84,35 @@ _dl_tlsdesc_undefweak: + .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak + + #ifdef SHARED +- .hidden _dl_tlsdesc_dynamic +- .global _dl_tlsdesc_dynamic +- .type _dl_tlsdesc_dynamic,@function +- +- /* This function is used for symbols that need dynamic TLS. +- +- %eax points to the TLS descriptor, such that 0(%eax) points to +- _dl_tlsdesc_dynamic itself, and 4(%eax) points to a struct +- tlsdesc_dynamic_arg object. It must return in %eax the offset +- between the thread pointer and the object denoted by the +- argument, without clobbering any registers. +- +- The assembly code that follows is a rendition of the following +- C code, hand-optimized a little bit. +- +-ptrdiff_t +-__attribute__ ((__regparm__ (1))) +-_dl_tlsdesc_dynamic (struct tlsdesc *tdp) +-{ +- struct tlsdesc_dynamic_arg *td = tdp->arg; +- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); +- if (__builtin_expect (td->gen_count <= dtv[0].counter +- && (dtv[td->tlsinfo.ti_module].pointer.val +- != TLS_DTV_UNALLOCATED), +- 1)) +- return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset +- - __thread_pointer; +- +- return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; +-} +-*/ +- cfi_startproc +- .align 16 +-_dl_tlsdesc_dynamic: +- /* Like all TLS resolvers, preserve call-clobbered registers. +- We need two scratch regs anyway. */ +- subl $28, %esp +- cfi_adjust_cfa_offset (28) +- movl %ecx, 20(%esp) +- movl %edx, 24(%esp) +- movl TLSDESC_ARG(%eax), %eax +- movl %gs:DTV_OFFSET, %edx +- movl TLSDESC_GEN_COUNT(%eax), %ecx +- cmpl (%edx), %ecx +- ja .Lslow +- movl TLSDESC_MODID(%eax), %ecx +- movl (%edx,%ecx,8), %edx +- cmpl $-1, %edx +- je .Lslow +- movl TLSDESC_MODOFF(%eax), %eax +- addl %edx, %eax +-.Lret: +- movl 20(%esp), %ecx +- subl %gs:0, %eax +- movl 24(%esp), %edx +- addl $28, %esp +- cfi_adjust_cfa_offset (-28) +- ret +- .p2align 4,,7 +-.Lslow: +- cfi_adjust_cfa_offset (28) +- call HIDDEN_JUMPTARGET (___tls_get_addr) +- jmp .Lret +- cfi_endproc +- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic ++# define USE_FNSAVE ++# define MINIMUM_ALIGNMENT 4 ++# define STATE_SAVE_ALIGNMENT 4 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fnsave ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef MINIMUM_ALIGNMENT ++# undef USE_FNSAVE ++ ++# define MINIMUM_ALIGNMENT 16 ++ ++# define USE_FXSAVE ++# define STATE_SAVE_ALIGNMENT 16 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef USE_FXSAVE ++ ++# define USE_XSAVE ++# define STATE_SAVE_ALIGNMENT 64 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef USE_XSAVE ++ ++# define USE_XSAVEC ++# define STATE_SAVE_ALIGNMENT 64 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef USE_XSAVEC + #endif /* SHARED */ +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index c1b6220992..f1f00825a6 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -1,5 +1,5 @@ + ifeq ($(subdir),csu) +-gen-as-const-headers += cpu-features-offsets.sym ++gen-as-const-headers += cpu-features-offsets.sym features-offsets.sym + endif + + ifeq ($(subdir),elf) +@@ -84,6 +84,11 @@ $(objpfx)tst-isa-level-1.out: $(objpfx)tst-isa-level-mod-1-baseline.so \ + endif + tst-ifunc-isa-2-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SSE4_2,-AVX,-AVX2,-AVX512F + tst-ifunc-isa-2-static-ENV = $(tst-ifunc-isa-2-ENV) ++ ++CFLAGS-tst-gnu2-tls2.c += -msse ++CFLAGS-tst-gnu2-tls2mod0.c += -msse2 -mtune=haswell ++CFLAGS-tst-gnu2-tls2mod1.c += -msse2 -mtune=haswell ++CFLAGS-tst-gnu2-tls2mod2.c += -msse2 -mtune=haswell + endif + + ifeq ($(subdir),math) +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index 87845e9fe8..769350814d 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -27,6 +27,22 @@ + extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) + attribute_hidden; + ++#if defined SHARED ++extern void _dl_tlsdesc_dynamic_fxsave (void) attribute_hidden; ++extern void _dl_tlsdesc_dynamic_xsave (void) attribute_hidden; ++extern void _dl_tlsdesc_dynamic_xsavec (void) attribute_hidden; ++ ++# ifndef __x86_64__ ++extern void _dl_tlsdesc_dynamic_fnsave (void) attribute_hidden; ++# endif ++#endif ++ ++#ifdef __x86_64__ ++extern void _dl_runtime_resolve_fxsave (void) attribute_hidden; ++extern void _dl_runtime_resolve_xsave (void) attribute_hidden; ++extern void _dl_runtime_resolve_xsavec (void) attribute_hidden; ++#endif ++ + #ifdef __LP64__ + static void + TUNABLE_CALLBACK (set_prefer_map_32bit_exec) (tunable_val_t *valp) +@@ -1083,6 +1099,44 @@ no_cpuid: + TUNABLE_CALLBACK (set_x86_shstk)); + #endif + ++ if (GLRO(dl_x86_cpu_features).xsave_state_size != 0) ++ { ++ if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC)) ++ { ++#ifdef __x86_64__ ++ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_xsavec; ++#endif ++#ifdef SHARED ++ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_xsavec; ++#endif ++ } ++ else ++ { ++#ifdef __x86_64__ ++ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_xsave; ++#endif ++#ifdef SHARED ++ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_xsave; ++#endif ++ } ++ } ++ else ++ { ++#ifdef __x86_64__ ++ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave; ++# ifdef SHARED ++ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; ++# endif ++#else ++# ifdef SHARED ++ if (CPU_FEATURE_USABLE_P (cpu_features, FXSR)) ++ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; ++ else ++ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave; ++# endif ++#endif ++ } ++ + #ifndef SHARED + /* NB: In libc.a, call init_cacheinfo. */ + init_cacheinfo (); +diff --git a/sysdeps/x86/dl-procinfo.c b/sysdeps/x86/dl-procinfo.c +index fef4a9f41e..c0dd06ceed 100644 +--- a/sysdeps/x86/dl-procinfo.c ++++ b/sysdeps/x86/dl-procinfo.c +@@ -86,3 +86,19 @@ PROCINFO_CLASS const char _dl_x86_platforms[4][9] + #else + , + #endif ++ ++#if defined SHARED && !IS_IN (ldconfig) ++# if !defined PROCINFO_DECL ++ ._dl_x86_tlsdesc_dynamic ++# else ++PROCINFO_CLASS void * _dl_x86_tlsdesc_dynamic ++# endif ++# ifndef PROCINFO_DECL ++= NULL ++# endif ++# ifdef PROCINFO_DECL ++; ++# else ++, ++# endif ++#endif +diff --git a/sysdeps/x86_64/features-offsets.sym b/sysdeps/x86/features-offsets.sym +similarity index 89% +rename from sysdeps/x86_64/features-offsets.sym +rename to sysdeps/x86/features-offsets.sym +index 9e4be3393a..77e990c705 100644 +--- a/sysdeps/x86_64/features-offsets.sym ++++ b/sysdeps/x86/features-offsets.sym +@@ -3,4 +3,6 @@ + #include + + RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET offsetof (struct rtld_global_ro, _dl_x86_cpu_features) ++#ifdef __x86_64__ + RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET offsetof (struct rtld_global, _dl_x86_feature_1) ++#endif +diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h +index 4e1dd96d4b..9c41b5bbfb 100644 +--- a/sysdeps/x86/sysdep.h ++++ b/sysdeps/x86/sysdep.h +@@ -70,6 +70,12 @@ + | (1 << X86_XSTATE_ZMM_H_ID)) + #endif + ++/* States which should be saved for TLSDESC_CALL and TLS_DESC_CALL. ++ Compiler assumes that all registers, including x87 FPU stack registers, ++ are unchanged after CALL, except for EFLAGS and RAX/EAX. */ ++#define TLSDESC_CALL_STATE_SAVE_MASK \ ++ (STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID)) ++ + /* Constants for bits in __x86_string_control: */ + + /* Avoid short distance REP MOVSB. */ +diff --git a/sysdeps/x86/tst-gnu2-tls2.c b/sysdeps/x86/tst-gnu2-tls2.c +new file mode 100644 +index 0000000000..de900a423b +--- /dev/null ++++ b/sysdeps/x86/tst-gnu2-tls2.c +@@ -0,0 +1,20 @@ ++#ifndef __x86_64__ ++#include ++ ++#define IS_SUPPORTED() CPU_FEATURE_ACTIVE (SSE2) ++#endif ++ ++/* Clear XMM0...XMM7 */ ++#define PREPARE_MALLOC() \ ++{ \ ++ asm volatile ("xorps %%xmm0, %%xmm0" : : : "xmm0" ); \ ++ asm volatile ("xorps %%xmm1, %%xmm1" : : : "xmm1" ); \ ++ asm volatile ("xorps %%xmm2, %%xmm2" : : : "xmm2" ); \ ++ asm volatile ("xorps %%xmm3, %%xmm3" : : : "xmm3" ); \ ++ asm volatile ("xorps %%xmm4, %%xmm4" : : : "xmm4" ); \ ++ asm volatile ("xorps %%xmm5, %%xmm5" : : : "xmm5" ); \ ++ asm volatile ("xorps %%xmm6, %%xmm6" : : : "xmm6" ); \ ++ asm volatile ("xorps %%xmm7, %%xmm7" : : : "xmm7" ); \ ++} ++ ++#include +diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile +index a3b0440aa7..36be2f6d56 100644 +--- a/sysdeps/x86_64/Makefile ++++ b/sysdeps/x86_64/Makefile +@@ -2,7 +2,7 @@ + long-double-fcts = yes + + ifeq ($(subdir),csu) +-gen-as-const-headers += features-offsets.sym link-defines.sym ++gen-as-const-headers += link-defines.sym + endif + + ifeq ($(subdir),gmon) +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index d35022c45f..f22f9abb82 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -67,9 +67,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + int lazy, int profile) + { + Elf64_Addr *got; +- extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_xsave (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_xsavec (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden; +@@ -120,15 +117,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + /* This function will get called to fix up the GOT entry + indicated by the offset on the stack, and then jump to + the resolved address. */ +- if (MINIMUM_X86_ISA_LEVEL >= AVX_X86_ISA_LEVEL +- || GLRO(dl_x86_cpu_features).xsave_state_size != 0) +- *(ElfW(Addr) *) (got + 2) +- = (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC) +- ? (ElfW(Addr)) &_dl_runtime_resolve_xsavec +- : (ElfW(Addr)) &_dl_runtime_resolve_xsave); +- else +- *(ElfW(Addr) *) (got + 2) +- = (ElfW(Addr)) &_dl_runtime_resolve_fxsave; ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) GLRO(dl_x86_64_runtime_resolve); + } + } + +@@ -380,7 +370,7 @@ and creates an unsatisfiable circular dependency.\n", + { + td->arg = _dl_make_tlsdesc_dynamic + (sym_map, sym->st_value + reloc->r_addend); +- td->entry = _dl_tlsdesc_dynamic; ++ td->entry = GLRO(dl_x86_tlsdesc_dynamic); + } + else + # endif +diff --git a/sysdeps/x86_64/dl-procinfo.c b/sysdeps/x86_64/dl-procinfo.c +index e15fb52e19..85d0dc3d09 100644 +--- a/sysdeps/x86_64/dl-procinfo.c ++++ b/sysdeps/x86_64/dl-procinfo.c +@@ -41,5 +41,21 @@ + + #include + ++#if !IS_IN (ldconfig) ++# if !defined PROCINFO_DECL && defined SHARED ++ ._dl_x86_64_runtime_resolve ++# else ++PROCINFO_CLASS void * _dl_x86_64_runtime_resolve ++# endif ++# ifndef PROCINFO_DECL ++= NULL ++# endif ++# if !defined SHARED || defined PROCINFO_DECL ++; ++# else ++, ++# endif ++#endif ++ + #undef PROCINFO_DECL + #undef PROCINFO_CLASS +diff --git a/sysdeps/x86_64/dl-tlsdesc-dynamic.h b/sysdeps/x86_64/dl-tlsdesc-dynamic.h +new file mode 100644 +index 0000000000..0c2e8d5320 +--- /dev/null ++++ b/sysdeps/x86_64/dl-tlsdesc-dynamic.h +@@ -0,0 +1,166 @@ ++/* Thread-local storage handling in the ELF dynamic linker. x86_64 version. ++ Copyright (C) 2004-2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SECTION ++# define SECTION(p) p ++#endif ++ ++#undef REGISTER_SAVE_AREA ++#undef LOCAL_STORAGE_AREA ++#undef BASE ++ ++#include "dl-trampoline-state.h" ++ ++ .section SECTION(.text),"ax",@progbits ++ ++ .hidden _dl_tlsdesc_dynamic ++ .global _dl_tlsdesc_dynamic ++ .type _dl_tlsdesc_dynamic,@function ++ ++ /* %rax points to the TLS descriptor, such that 0(%rax) points to ++ _dl_tlsdesc_dynamic itself, and 8(%rax) points to a struct ++ tlsdesc_dynamic_arg object. It must return in %rax the offset ++ between the thread pointer and the object denoted by the ++ argument, without clobbering any registers. ++ ++ The assembly code that follows is a rendition of the following ++ C code, hand-optimized a little bit. ++ ++ptrdiff_t ++_dl_tlsdesc_dynamic (register struct tlsdesc *tdp asm ("%rax")) ++{ ++ struct tlsdesc_dynamic_arg *td = tdp->arg; ++ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); ++ if (__builtin_expect (td->gen_count <= dtv[0].counter ++ && (dtv[td->tlsinfo.ti_module].pointer.val ++ != TLS_DTV_UNALLOCATED), ++ 1)) ++ return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset ++ - __thread_pointer; ++ ++ return __tls_get_addr_internal (&td->tlsinfo) - __thread_pointer; ++} ++*/ ++ cfi_startproc ++ .align 16 ++_dl_tlsdesc_dynamic: ++ _CET_ENDBR ++ /* Preserve call-clobbered registers that we modify. ++ We need two scratch regs anyway. */ ++ movq %rsi, -16(%rsp) ++ mov %fs:DTV_OFFSET, %RSI_LP ++ movq %rdi, -8(%rsp) ++ movq TLSDESC_ARG(%rax), %rdi ++ movq (%rsi), %rax ++ cmpq %rax, TLSDESC_GEN_COUNT(%rdi) ++ ja 2f ++ movq TLSDESC_MODID(%rdi), %rax ++ salq $4, %rax ++ movq (%rax,%rsi), %rax ++ cmpq $-1, %rax ++ je 2f ++ addq TLSDESC_MODOFF(%rdi), %rax ++1: ++ movq -16(%rsp), %rsi ++ sub %fs:0, %RAX_LP ++ movq -8(%rsp), %rdi ++ ret ++2: ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++ movq %rbx, -24(%rsp) ++ mov %RSP_LP, %RBX_LP ++ cfi_def_cfa_register(%rbx) ++ and $-STATE_SAVE_ALIGNMENT, %RSP_LP ++#endif ++#ifdef REGISTER_SAVE_AREA ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK ++ /* STATE_SAVE_OFFSET has space for 8 integer registers. But we ++ need space for RCX, RDX, RSI, RDI, R8, R9, R10 and R11, plus ++ RBX above. */ ++ sub $(REGISTER_SAVE_AREA + STATE_SAVE_ALIGNMENT), %RSP_LP ++# else ++ sub $REGISTER_SAVE_AREA, %RSP_LP ++ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) ++# endif ++#else ++ /* Allocate stack space of the required size to save the state. */ ++ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP ++#endif ++ /* Besides rdi and rsi, saved above, save rcx, rdx, r8, r9, ++ r10 and r11. */ ++ movq %rcx, REGISTER_SAVE_RCX(%rsp) ++ movq %rdx, REGISTER_SAVE_RDX(%rsp) ++ movq %r8, REGISTER_SAVE_R8(%rsp) ++ movq %r9, REGISTER_SAVE_R9(%rsp) ++ movq %r10, REGISTER_SAVE_R10(%rsp) ++ movq %r11, REGISTER_SAVE_R11(%rsp) ++#ifdef USE_FXSAVE ++ fxsave STATE_SAVE_OFFSET(%rsp) ++#else ++ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ /* Clear the XSAVE Header. */ ++# ifdef USE_XSAVE ++ movq %rdx, (STATE_SAVE_OFFSET + 512)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8)(%rsp) ++# endif ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 2)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 3)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 4)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 5)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 6)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 7)(%rsp) ++# ifdef USE_XSAVE ++ xsave STATE_SAVE_OFFSET(%rsp) ++# else ++ xsavec STATE_SAVE_OFFSET(%rsp) ++# endif ++#endif ++ /* %rdi already points to the tlsinfo data structure. */ ++ call HIDDEN_JUMPTARGET (__tls_get_addr) ++ # Get register content back. ++#ifdef USE_FXSAVE ++ fxrstor STATE_SAVE_OFFSET(%rsp) ++#else ++ /* Save and retore __tls_get_addr return value stored in RAX. */ ++ mov %RAX_LP, %RCX_LP ++ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ xrstor STATE_SAVE_OFFSET(%rsp) ++ mov %RCX_LP, %RAX_LP ++#endif ++ movq REGISTER_SAVE_R11(%rsp), %r11 ++ movq REGISTER_SAVE_R10(%rsp), %r10 ++ movq REGISTER_SAVE_R9(%rsp), %r9 ++ movq REGISTER_SAVE_R8(%rsp), %r8 ++ movq REGISTER_SAVE_RDX(%rsp), %rdx ++ movq REGISTER_SAVE_RCX(%rsp), %rcx ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++ mov %RBX_LP, %RSP_LP ++ cfi_def_cfa_register(%rsp) ++ movq -24(%rsp), %rbx ++ cfi_restore(%rbx) ++#else ++ add $REGISTER_SAVE_AREA, %RSP_LP ++ cfi_adjust_cfa_offset(-REGISTER_SAVE_AREA) ++#endif ++ jmp 1b ++ cfi_endproc ++ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic ++ ++#undef STATE_SAVE_ALIGNMENT +diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S +index 4579424bf7..6f97128187 100644 +--- a/sysdeps/x86_64/dl-tlsdesc.S ++++ b/sysdeps/x86_64/dl-tlsdesc.S +@@ -18,7 +18,19 @@ + + #include + #include ++#include ++#include + #include "tlsdesc.h" ++#include "dl-trampoline-save.h" ++ ++/* Area on stack to save and restore registers used for parameter ++ passing when calling _dl_tlsdesc_dynamic. */ ++#define REGISTER_SAVE_RCX 0 ++#define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8) ++#define REGISTER_SAVE_R8 (REGISTER_SAVE_RDX + 8) ++#define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8) ++#define REGISTER_SAVE_R10 (REGISTER_SAVE_R9 + 8) ++#define REGISTER_SAVE_R11 (REGISTER_SAVE_R10 + 8) + + .text + +@@ -67,80 +79,24 @@ _dl_tlsdesc_undefweak: + .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak + + #ifdef SHARED +- .hidden _dl_tlsdesc_dynamic +- .global _dl_tlsdesc_dynamic +- .type _dl_tlsdesc_dynamic,@function +- +- /* %rax points to the TLS descriptor, such that 0(%rax) points to +- _dl_tlsdesc_dynamic itself, and 8(%rax) points to a struct +- tlsdesc_dynamic_arg object. It must return in %rax the offset +- between the thread pointer and the object denoted by the +- argument, without clobbering any registers. +- +- The assembly code that follows is a rendition of the following +- C code, hand-optimized a little bit. +- +-ptrdiff_t +-_dl_tlsdesc_dynamic (register struct tlsdesc *tdp asm ("%rax")) +-{ +- struct tlsdesc_dynamic_arg *td = tdp->arg; +- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); +- if (__builtin_expect (td->gen_count <= dtv[0].counter +- && (dtv[td->tlsinfo.ti_module].pointer.val +- != TLS_DTV_UNALLOCATED), +- 1)) +- return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset +- - __thread_pointer; +- +- return __tls_get_addr_internal (&td->tlsinfo) - __thread_pointer; +-} +-*/ +- cfi_startproc +- .align 16 +-_dl_tlsdesc_dynamic: +- _CET_ENDBR +- /* Preserve call-clobbered registers that we modify. +- We need two scratch regs anyway. */ +- movq %rsi, -16(%rsp) +- mov %fs:DTV_OFFSET, %RSI_LP +- movq %rdi, -8(%rsp) +- movq TLSDESC_ARG(%rax), %rdi +- movq (%rsi), %rax +- cmpq %rax, TLSDESC_GEN_COUNT(%rdi) +- ja .Lslow +- movq TLSDESC_MODID(%rdi), %rax +- salq $4, %rax +- movq (%rax,%rsi), %rax +- cmpq $-1, %rax +- je .Lslow +- addq TLSDESC_MODOFF(%rdi), %rax +-.Lret: +- movq -16(%rsp), %rsi +- sub %fs:0, %RAX_LP +- movq -8(%rsp), %rdi +- ret +-.Lslow: +- /* Besides rdi and rsi, saved above, save rdx, rcx, r8, r9, +- r10 and r11. Also, align the stack, that's off by 8 bytes. */ +- subq $72, %rsp +- cfi_adjust_cfa_offset (72) +- movq %rdx, 8(%rsp) +- movq %rcx, 16(%rsp) +- movq %r8, 24(%rsp) +- movq %r9, 32(%rsp) +- movq %r10, 40(%rsp) +- movq %r11, 48(%rsp) +- /* %rdi already points to the tlsinfo data structure. */ +- call HIDDEN_JUMPTARGET (__tls_get_addr) +- movq 8(%rsp), %rdx +- movq 16(%rsp), %rcx +- movq 24(%rsp), %r8 +- movq 32(%rsp), %r9 +- movq 40(%rsp), %r10 +- movq 48(%rsp), %r11 +- addq $72, %rsp +- cfi_adjust_cfa_offset (-72) +- jmp .Lret +- cfi_endproc +- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic ++# define USE_FXSAVE ++# define STATE_SAVE_ALIGNMENT 16 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef USE_FXSAVE ++ ++# define USE_XSAVE ++# define STATE_SAVE_ALIGNMENT 64 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef USE_XSAVE ++ ++# define USE_XSAVEC ++# define STATE_SAVE_ALIGNMENT 64 ++# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec ++# include "dl-tlsdesc-dynamic.h" ++# undef _dl_tlsdesc_dynamic ++# undef USE_XSAVEC + #endif /* SHARED */ +diff --git a/sysdeps/x86_64/dl-trampoline-save.h b/sysdeps/x86_64/dl-trampoline-save.h +new file mode 100644 +index 0000000000..84eac4a8ac +--- /dev/null ++++ b/sysdeps/x86_64/dl-trampoline-save.h +@@ -0,0 +1,34 @@ ++/* x86-64 PLT trampoline register save macros. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef DL_STACK_ALIGNMENT ++/* Due to GCC bug: ++ ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 ++ ++ __tls_get_addr may be called with 8-byte stack alignment. Although ++ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume ++ that stack will be always aligned at 16 bytes. */ ++# define DL_STACK_ALIGNMENT 8 ++#endif ++ ++/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align ++ stack to 16 bytes before calling _dl_fixup. */ ++#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ ++ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ ++ || 16 > DL_STACK_ALIGNMENT) +diff --git a/sysdeps/x86_64/dl-trampoline-state.h b/sysdeps/x86_64/dl-trampoline-state.h +new file mode 100644 +index 0000000000..575f120797 +--- /dev/null ++++ b/sysdeps/x86_64/dl-trampoline-state.h +@@ -0,0 +1,51 @@ ++/* x86-64 PLT dl-trampoline state macros. ++ Copyright (C) 2024 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 ++ . */ ++ ++#if (STATE_SAVE_ALIGNMENT % 16) != 0 ++# error STATE_SAVE_ALIGNMENT must be multiple of 16 ++#endif ++ ++#if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0 ++# error STATE_SAVE_OFFSET must be multiple of STATE_SAVE_ALIGNMENT ++#endif ++ ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++/* Local stack area before jumping to function address: RBX. */ ++# define LOCAL_STORAGE_AREA 8 ++# define BASE rbx ++# ifdef USE_FXSAVE ++/* Use fxsave to save XMM registers. */ ++# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET) ++# if (REGISTER_SAVE_AREA % 16) != 0 ++# error REGISTER_SAVE_AREA must be multiple of 16 ++# endif ++# endif ++#else ++# ifndef USE_FXSAVE ++# error USE_FXSAVE must be defined ++# endif ++/* Use fxsave to save XMM registers. */ ++# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8) ++/* Local stack area before jumping to function address: All saved ++ registers. */ ++# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA ++# define BASE rsp ++# if (REGISTER_SAVE_AREA % 16) != 8 ++# error REGISTER_SAVE_AREA must be odd multiple of 8 ++# endif ++#endif +diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S +index 3c18500690..e84d6ffcb3 100644 +--- a/sysdeps/x86_64/dl-trampoline.S ++++ b/sysdeps/x86_64/dl-trampoline.S +@@ -22,25 +22,7 @@ + #include + #include + #include +- +-#ifndef DL_STACK_ALIGNMENT +-/* Due to GCC bug: +- +- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 +- +- __tls_get_addr may be called with 8-byte stack alignment. Although +- this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume +- that stack will be always aligned at 16 bytes. We use unaligned +- 16-byte move to load and store SSE registers, which has no penalty +- on modern processors if stack is 16-byte aligned. */ +-# define DL_STACK_ALIGNMENT 8 +-#endif +- +-/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align +- stack to 16 bytes before calling _dl_fixup. */ +-#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ +- (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ +- || 16 > DL_STACK_ALIGNMENT) ++#include "dl-trampoline-save.h" + + /* Area on stack to save and restore registers used for parameter + passing when calling _dl_fixup. */ +diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h +index 70ba6ec6f5..8a424f8f64 100644 +--- a/sysdeps/x86_64/dl-trampoline.h ++++ b/sysdeps/x86_64/dl-trampoline.h +@@ -27,39 +27,7 @@ + # undef LOCAL_STORAGE_AREA + # undef BASE + +-# if (STATE_SAVE_ALIGNMENT % 16) != 0 +-# error STATE_SAVE_ALIGNMENT must be multiple of 16 +-# endif +- +-# if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0 +-# error STATE_SAVE_OFFSET must be multiple of STATE_SAVE_ALIGNMENT +-# endif +- +-# if DL_RUNTIME_RESOLVE_REALIGN_STACK +-/* Local stack area before jumping to function address: RBX. */ +-# define LOCAL_STORAGE_AREA 8 +-# define BASE rbx +-# ifdef USE_FXSAVE +-/* Use fxsave to save XMM registers. */ +-# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET) +-# if (REGISTER_SAVE_AREA % 16) != 0 +-# error REGISTER_SAVE_AREA must be multiple of 16 +-# endif +-# endif +-# else +-# ifndef USE_FXSAVE +-# error USE_FXSAVE must be defined +-# endif +-/* Use fxsave to save XMM registers. */ +-# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8) +-/* Local stack area before jumping to function address: All saved +- registers. */ +-# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA +-# define BASE rsp +-# if (REGISTER_SAVE_AREA % 16) != 8 +-# error REGISTER_SAVE_AREA must be odd multiple of 8 +-# endif +-# endif ++# include "dl-trampoline-state.h" + + .globl _dl_runtime_resolve + .hidden _dl_runtime_resolve +-- +2.27.0 + diff --git a/x86-cet-Add-fcf-protection-none-before-fcf-protectio.patch b/x86-cet-Add-fcf-protection-none-before-fcf-protectio.patch new file mode 100644 index 0000000..ffe5017 --- /dev/null +++ b/x86-cet-Add-fcf-protection-none-before-fcf-protectio.patch @@ -0,0 +1,85 @@ +From 78b4845046b3fbe3e4cd6b5e03656dd62342f349 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 1 Jan 2024 07:55:18 -0800 +Subject: [PATCH] x86/cet: Add -fcf-protection=none before + -fcf-protection=branch + +When shadow stack is enabled, some CET tests failed when compiled with +GCC 14: + +FAIL: elf/tst-cet-legacy-4 +FAIL: elf/tst-cet-legacy-5a +FAIL: elf/tst-cet-legacy-6a + +which are caused by + +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113039 + +These tests use -fcf-protection -fcf-protection=branch and assume that +-fcf-protection=branch will override -fcf-protection. But this GCC 14 +commit: + +https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=1c6231c05bdcca + +changed the -fcf-protection behavior such that + +-fcf-protection -fcf-protection=branch + +is treated the same as + +-fcf-protection + +Use + +-fcf-protection -fcf-protection=none -fcf-protection=branch + +as the workaround. This fixes BZ #31187. + +Tested with GCC 13 and GCC 14 on Intel Tiger Lake. +Reviewed-by: Noah Goldstein + +(cherry picked from commit b5dcccfb12385ee492eb074f6beb9ead56b5e5fd) +--- + sysdeps/x86/Makefile | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index d751eaedf4..2bd7e358e5 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -213,12 +213,12 @@ modules-names += \ + tst-cet-legacy-mod-6c \ + # modules-names + +-CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch ++CFLAGS-tst-cet-legacy-2.c += -fcf-protection=none -fcf-protection=branch + CFLAGS-tst-cet-legacy-2a.c += -fcf-protection + CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch ++CFLAGS-tst-cet-legacy-4.c += -fcf-protection=none -fcf-protection=branch + CPPFLAGS-tst-cet-legacy-4a.c += -DCET_IS_PERMISSIVE=1 + CFLAGS-tst-cet-legacy-4a.c += -fcf-protection + CFLAGS-tst-cet-legacy-4b.c += -fcf-protection +@@ -229,7 +229,7 @@ CPPFLAGS-tst-cet-legacy-5a.c += -DCET_IS_PERMISSIVE=1 + endif + CFLAGS-tst-cet-legacy-5b.c += -fcf-protection -mshstk + CPPFLAGS-tst-cet-legacy-5b.c += -DCET_DISABLED_BY_ENV=1 +-CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=branch ++CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none -fcf-protection=branch + CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection + CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection + CFLAGS-tst-cet-legacy-6a.c += -fcf-protection -mshstk +@@ -238,7 +238,7 @@ CPPFLAGS-tst-cet-legacy-6a.c += -DCET_IS_PERMISSIVE=1 + endif + CFLAGS-tst-cet-legacy-6b.c += -fcf-protection -mshstk + CPPFLAGS-tst-cet-legacy-6b.c += -DCET_DISABLED_BY_ENV=1 +-CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=branch ++CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none -fcf-protection=branch + CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection + CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection + CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none +-- +2.27.0 + diff --git a/x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hwcap.patch b/x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hwcap.patch new file mode 100644 index 0000000..2dacaac --- /dev/null +++ b/x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hwcap.patch @@ -0,0 +1,83 @@ +From db563af070a3ad4c24c1430eaa050863569ba0e7 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 17 Mar 2023 16:21:49 -0700 +Subject: [PATCH] x86/cet: Add tests for + GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK + +Verify that GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK turns off shadow +stack properly. + +(cherry picked from commit 9424ce80c2a08f4dfc06d5442b770ed5ec798c4b) +--- + sysdeps/x86/Makefile | 7 +++++++ + sysdeps/x86/tst-shstk-legacy-1c-static.c | 1 + + sysdeps/x86/tst-shstk-legacy-1c.c | 20 ++++++++++++++++++++ + 3 files changed, 28 insertions(+) + create mode 100644 sysdeps/x86/tst-shstk-legacy-1c-static.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1c.c + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 23f3ac1430..b857ad6ea6 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -171,10 +171,13 @@ tests += \ + tst-shstk-legacy-1a-static \ + tst-shstk-legacy-1b \ + tst-shstk-legacy-1b-static \ ++ tst-shstk-legacy-1c \ ++ tst-shstk-legacy-1c-static \ + # tests + tests-static += \ + tst-shstk-legacy-1a-static \ + tst-shstk-legacy-1b-static \ ++ tst-shstk-legacy-1c-static \ + # tests-static + extra-objs += \ + tst-shstk-legacy-1-extra.o \ +@@ -272,6 +275,10 @@ $(objpfx)tst-shstk-legacy-1a: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1a-static: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1b: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1b-static: $(objpfx)tst-shstk-legacy-1-extra.o ++tst-shstk-legacy-1c-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK ++tst-shstk-legacy-1c-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK ++$(objpfx)tst-shstk-legacy-1c: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1c-static: $(objpfx)tst-shstk-legacy-1-extra.o + endif + + # Add -fcf-protection to CFLAGS when CET is enabled. +diff --git a/sysdeps/x86/tst-shstk-legacy-1c-static.c b/sysdeps/x86/tst-shstk-legacy-1c-static.c +new file mode 100644 +index 0000000000..91ea346aaf +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1c-static.c +@@ -0,0 +1 @@ ++#include "tst-shstk-legacy-1c.c" +diff --git a/sysdeps/x86/tst-shstk-legacy-1c.c b/sysdeps/x86/tst-shstk-legacy-1c.c +new file mode 100644 +index 0000000000..eb218c6c70 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1c.c +@@ -0,0 +1,20 @@ ++/* Check that legacy shadow stack code won't trigger segfault with ++ GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK ++ Copyright (C) 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 "tst-shstk-legacy-1a.c" +-- +2.27.0 + diff --git a/x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mode.patch b/x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mode.patch new file mode 100644 index 0000000..525b094 --- /dev/null +++ b/x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mode.patch @@ -0,0 +1,51 @@ +From 2c763f814e581895539e7762461aef62cc9465fd Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 28 Mar 2023 13:52:36 -0700 +Subject: [PATCH] x86/cet: Check CPU_FEATURE_ACTIVE in permissive mode + +Verify that CPU_FEATURE_ACTIVE works properly in permissive mode. + +(cherry picked from commit 4d8a01d2b0963f7c7714ff53c313430599f0722f) +--- + sysdeps/x86/Makefile | 1 + + sysdeps/x86/tst-cet-legacy-4.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 1bf6ff9e11..6911a07a87 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -219,6 +219,7 @@ CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch ++CPPFLAGS-tst-cet-legacy-4a.c += -DCET_IS_PERMISSIVE=1 + CFLAGS-tst-cet-legacy-4a.c += -fcf-protection + CFLAGS-tst-cet-legacy-4b.c += -fcf-protection + CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none +diff --git a/sysdeps/x86/tst-cet-legacy-4.c b/sysdeps/x86/tst-cet-legacy-4.c +index d75fb0e61c..c098120253 100644 +--- a/sysdeps/x86/tst-cet-legacy-4.c ++++ b/sysdeps/x86/tst-cet-legacy-4.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include + +@@ -40,6 +41,10 @@ do_test (void) + return 0; + } + ++#ifdef CET_IS_PERMISSIVE ++ TEST_VERIFY (!CPU_FEATURE_ACTIVE (IBT) && !CPU_FEATURE_ACTIVE (SHSTK)); ++#endif ++ + fp = dlsym (h, "test"); + if (fp == NULL) + FAIL_EXIT1 ("cannot get symbol 'test': %s\n", dlerror ()); +-- +2.27.0 + diff --git a/x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disable.patch b/x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disable.patch new file mode 100644 index 0000000..544cfed --- /dev/null +++ b/x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disable.patch @@ -0,0 +1,63 @@ +From a4003d1500e4a640dd84d31904ed4bb0ce9d91c7 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 10 Mar 2023 13:18:10 -0800 +Subject: [PATCH] x86/cet: Check CPU_FEATURE_ACTIVE when CET is disabled + +Verify that CPU_FEATURE_ACTIVE (SHSTK) works properly when CET is +disabled. + +(cherry picked from commit 71c0cc3357fe6d72f1dbef1c695e54b117d91b96) +--- + sysdeps/x86/Makefile | 5 +++++ + sysdeps/x86/tst-cet-legacy-10a-static.c | 2 ++ + sysdeps/x86/tst-cet-legacy-10a.c | 2 ++ + 3 files changed, 9 insertions(+) + create mode 100644 sysdeps/x86/tst-cet-legacy-10a-static.c + create mode 100644 sysdeps/x86/tst-cet-legacy-10a.c + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index a41598adf9..23f3ac1430 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -156,10 +156,13 @@ tests += \ + tst-cet-legacy-9-static \ + tst-cet-legacy-10 \ + tst-cet-legacy-10-static \ ++ tst-cet-legacy-10a \ ++ tst-cet-legacy-10a-static \ + # tests + tests-static += \ + tst-cet-legacy-9-static \ + tst-cet-legacy-10-static \ ++ tst-cet-legacy-10a-static \ + # tests-static + tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd) + +@@ -226,6 +229,8 @@ CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection + CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-10.c += -mshstk + CFLAGS-tst-cet-legacy-10-static.c += -mshstk ++CFLAGS-tst-cet-legacy-10a.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-10a-static.c += -fcf-protection=none + + CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none + CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none +diff --git a/sysdeps/x86/tst-cet-legacy-10a-static.c b/sysdeps/x86/tst-cet-legacy-10a-static.c +new file mode 100644 +index 0000000000..05073a5d1e +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-10a-static.c +@@ -0,0 +1,2 @@ ++#pragma GCC target ("shstk") ++#include "tst-cet-legacy-10.c" +diff --git a/sysdeps/x86/tst-cet-legacy-10a.c b/sysdeps/x86/tst-cet-legacy-10a.c +new file mode 100644 +index 0000000000..05073a5d1e +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-10a.c +@@ -0,0 +1,2 @@ ++#pragma GCC target ("shstk") ++#include "tst-cet-legacy-10.c" +-- +2.27.0 + diff --git a/x86-cet-Check-feature_1-in-TCB-for-active-IBT-and-SH.patch b/x86-cet-Check-feature_1-in-TCB-for-active-IBT-and-SH.patch new file mode 100644 index 0000000..ac934eb --- /dev/null +++ b/x86-cet-Check-feature_1-in-TCB-for-active-IBT-and-SH.patch @@ -0,0 +1,91 @@ +From 027b3218116180c25521421d01889b3e7394deb6 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 29 Dec 2023 08:43:52 -0800 +Subject: [PATCH] x86/cet: Check feature_1 in TCB for active IBT and + SHSTK + +Initially, IBT and SHSTK are marked as active when CPU supports them +and CET are enabled in glibc. They can be disabled early by tunables +before relocation. Since after relocation, GLRO(dl_x86_cpu_features) +becomes read-only, we can't update GLRO(dl_x86_cpu_features) to mark +IBT and SHSTK as inactive. Instead, check the feature_1 field in TCB +to decide if IBT and SHST are active. + +(cherry picked from commit d360dcc001cb12504cd3e8dbddee20df6bebb0f8) +--- + sysdeps/x86/bits/platform/x86.h | 8 ++++++++ + sysdeps/x86/get-cpuid-feature-leaf.c | 11 ++++++++++- + sysdeps/x86/sys/platform/x86.h | 17 +++++++++++++++++ + 3 files changed, 35 insertions(+), 1 deletion(-) + +diff --git a/sysdeps/x86/bits/platform/x86.h b/sysdeps/x86/bits/platform/x86.h +index 88ca071aa7..fb8676b968 100644 +--- a/sysdeps/x86/bits/platform/x86.h ++++ b/sysdeps/x86/bits/platform/x86.h +@@ -327,3 +327,11 @@ enum + + x86_cpu_PTWRITE = x86_cpu_index_14_ecx_0_ebx + 4 + }; ++ ++/* Bits in the feature_1 field in TCB. */ ++ ++enum ++{ ++ x86_feature_1_ibt = 1U << 0, ++ x86_feature_1_shstk = 1U << 1 ++}; +diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c +index 9317a6b494..f69936b31e 100644 +--- a/sysdeps/x86/get-cpuid-feature-leaf.c ++++ b/sysdeps/x86/get-cpuid-feature-leaf.c +@@ -15,9 +15,18 @@ + License along with the GNU C Library; if not, see + . */ + +- ++#include ++#include + #include + ++#ifdef __x86_64__ ++# ifdef __LP64__ ++_Static_assert (FEATURE_1_OFFSET == 72, "FEATURE_1_OFFSET != 72"); ++# else ++_Static_assert (FEATURE_1_OFFSET == 40, "FEATURE_1_OFFSET != 40"); ++# endif ++#endif ++ + const struct cpuid_feature * + __x86_get_cpuid_feature_leaf (unsigned int leaf) + { +diff --git a/sysdeps/x86/sys/platform/x86.h b/sysdeps/x86/sys/platform/x86.h +index 1ea2c5fc0b..89b1b16f22 100644 +--- a/sysdeps/x86/sys/platform/x86.h ++++ b/sysdeps/x86/sys/platform/x86.h +@@ -45,6 +45,23 @@ x86_cpu_present (unsigned int __index) + static __inline__ _Bool + x86_cpu_active (unsigned int __index) + { ++ if (__index == x86_cpu_IBT || __index == x86_cpu_SHSTK) ++ { ++#ifdef __x86_64__ ++ unsigned int __feature_1; ++# ifdef __LP64__ ++ __asm__ ("mov %%fs:72, %0" : "=r" (__feature_1)); ++# else ++ __asm__ ("mov %%fs:40, %0" : "=r" (__feature_1)); ++# endif ++ if (__index == x86_cpu_IBT) ++ return __feature_1 & x86_feature_1_ibt; ++ else ++ return __feature_1 & x86_feature_1_shstk; ++#else ++ return false; ++#endif ++ } + const struct cpuid_feature *__ptr = __x86_get_cpuid_feature_leaf + (__index / (8 * sizeof (unsigned int) * 4)); + unsigned int __reg +-- +2.27.0 + diff --git a/x86-cet-Check-legacy-shadow-stack-applications.patch b/x86-cet-Check-legacy-shadow-stack-applications.patch new file mode 100644 index 0000000..48ef9f3 --- /dev/null +++ b/x86-cet-Check-legacy-shadow-stack-applications.patch @@ -0,0 +1,211 @@ +From d5db2ef4ce27321d45480c9a6d35fc7e2106790a Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 21 Mar 2023 12:53:24 -0700 +Subject: [PATCH] x86/cet: Check legacy shadow stack applications + +Add tests to verify that legacy shadow stack applications run properly +when shadow stack is enabled in Linux kernel. + +(cherry picked from commit f418fe6f973300c4c61461ed241928cba11017c2) +--- + sysdeps/x86/Makefile | 23 ++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1-extra.S | 35 ++++++++++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1a-static.c | 1 + + sysdeps/x86/tst-shstk-legacy-1a.c | 32 ++++++++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1b-static.c | 1 + + sysdeps/x86/tst-shstk-legacy-1b.c | 38 ++++++++++++++++++++++++ + 6 files changed, 130 insertions(+) + create mode 100644 sysdeps/x86/tst-shstk-legacy-1-extra.S + create mode 100644 sysdeps/x86/tst-shstk-legacy-1a-static.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1a.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1b-static.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1b.c + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 3d936ed537..a41598adf9 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -162,6 +162,21 @@ tests-static += \ + tst-cet-legacy-10-static \ + # tests-static + tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd) ++ ++tests += \ ++ tst-shstk-legacy-1a \ ++ tst-shstk-legacy-1a-static \ ++ tst-shstk-legacy-1b \ ++ tst-shstk-legacy-1b-static \ ++# tests ++tests-static += \ ++ tst-shstk-legacy-1a-static \ ++ tst-shstk-legacy-1b-static \ ++# tests-static ++extra-objs += \ ++ tst-shstk-legacy-1-extra.o \ ++# extra-objs ++ + tests += \ + tst-cet-legacy-4a \ + tst-cet-legacy-4b \ +@@ -212,6 +227,9 @@ CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-10.c += -mshstk + CFLAGS-tst-cet-legacy-10-static.c += -mshstk + ++CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none ++ + $(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ + $(objpfx)tst-cet-legacy-mod-2.so + $(objpfx)tst-cet-legacy-1a: $(objpfx)tst-cet-legacy-mod-1.so \ +@@ -244,6 +262,11 @@ $(objpfx)tst-cet-legacy-6b.out: $(objpfx)tst-cet-legacy-mod-6a.so \ + tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK + tst-cet-legacy-9-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK + tst-cet-legacy-9-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK ++ ++$(objpfx)tst-shstk-legacy-1a: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1a-static: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1b: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1b-static: $(objpfx)tst-shstk-legacy-1-extra.o + endif + + # Add -fcf-protection to CFLAGS when CET is enabled. +diff --git a/sysdeps/x86/tst-shstk-legacy-1-extra.S b/sysdeps/x86/tst-shstk-legacy-1-extra.S +new file mode 100644 +index 0000000000..f3adb9f639 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1-extra.S +@@ -0,0 +1,35 @@ ++/* Legacy shadow stack code. ++ Copyright (C) 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 ++ . */ ++ ++ .text ++ .globl legacy ++ .type legacy, @function ++legacy: ++ .cfi_startproc ++#ifdef __x86_64__ ++ movq (%rsp), %rax ++ addq $8, %rsp ++ jmp *%rax ++#else ++ movl (%esp), %eax ++ addl $4, %esp ++ jmp *%eax ++#endif ++ .cfi_endproc ++ .size legacy, .-legacy ++ .section .note.GNU-stack,"",@progbits +diff --git a/sysdeps/x86/tst-shstk-legacy-1a-static.c b/sysdeps/x86/tst-shstk-legacy-1a-static.c +new file mode 100644 +index 0000000000..dd549890a0 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1a-static.c +@@ -0,0 +1 @@ ++#include "tst-shstk-legacy-1a.c" +diff --git a/sysdeps/x86/tst-shstk-legacy-1a.c b/sysdeps/x86/tst-shstk-legacy-1a.c +new file mode 100644 +index 0000000000..c6f5810838 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1a.c +@@ -0,0 +1,32 @@ ++/* Check that legacy shadow stack code won't trigger segfault. ++ Copyright (C) 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 ++ ++/* Check that legacy shadow stack code won't trigger segfault. */ ++extern void legacy (void); ++ ++static int ++do_test (void) ++{ ++ legacy (); ++ return EXIT_SUCCESS; ++} ++ ++#include +diff --git a/sysdeps/x86/tst-shstk-legacy-1b-static.c b/sysdeps/x86/tst-shstk-legacy-1b-static.c +new file mode 100644 +index 0000000000..4945344675 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1b-static.c +@@ -0,0 +1 @@ ++#include "tst-shstk-legacy-1b.c" +diff --git a/sysdeps/x86/tst-shstk-legacy-1b.c b/sysdeps/x86/tst-shstk-legacy-1b.c +new file mode 100644 +index 0000000000..05231e60ae +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1b.c +@@ -0,0 +1,38 @@ ++/* Check that legacy shadow stack code will trigger segfault. ++ Copyright (C) 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 ++ ++/* Check that legacy shadow stack code will trigger segfault. */ ++extern void legacy (void); ++ ++static int ++do_test (void) ++{ ++ if (!CPU_FEATURE_ACTIVE (SHSTK)) ++ return EXIT_UNSUPPORTED; ++ ++ legacy (); ++ return EXIT_FAILURE; ++} ++ ++#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (SHSTK) ? SIGSEGV : 0) ++#include +-- +2.27.0 + diff --git a/x86-cet-Check-legacy-shadow-stack-code-in-.init_arra.patch b/x86-cet-Check-legacy-shadow-stack-code-in-.init_arra.patch new file mode 100644 index 0000000..92142c7 --- /dev/null +++ b/x86-cet-Check-legacy-shadow-stack-code-in-.init_arra.patch @@ -0,0 +1,458 @@ +From 1192cdd722824e0ebfb133b51e539a663e56b6d0 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 22 Mar 2023 13:34:55 -0700 +Subject: [PATCH] x86/cet: Check legacy shadow stack code in .init_array + section + +Verify that legacy shadow stack code in .init_array section in application +and shared library, which are marked as shadow stack enabled, will trigger +segfault. + +(cherry picked from commit 28bd6f832d4c8ec9a223c153427c1ab6fd19a548) +--- + sysdeps/x86/Makefile | 36 +++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1d-static.c | 1 + + sysdeps/x86/tst-shstk-legacy-1d.c | 47 ++++++++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1e-static.c | 1 + + sysdeps/x86/tst-shstk-legacy-1e-static.sh | 32 ++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1e.c | 53 +++++++++++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1e.sh | 34 +++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1f.c | 29 +++++++++++++ + sysdeps/x86/tst-shstk-legacy-1g.c | 35 +++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1g.sh | 34 +++++++++++++++ + sysdeps/x86/tst-shstk-legacy-mod-1.c | 28 ++++++++++++ + 11 files changed, 330 insertions(+) + create mode 100644 sysdeps/x86/tst-shstk-legacy-1d-static.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1d.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1e-static.c + create mode 100755 sysdeps/x86/tst-shstk-legacy-1e-static.sh + create mode 100644 sysdeps/x86/tst-shstk-legacy-1e.c + create mode 100755 sysdeps/x86/tst-shstk-legacy-1e.sh + create mode 100644 sysdeps/x86/tst-shstk-legacy-1f.c + create mode 100644 sysdeps/x86/tst-shstk-legacy-1g.c + create mode 100755 sysdeps/x86/tst-shstk-legacy-1g.sh + create mode 100644 sysdeps/x86/tst-shstk-legacy-mod-1.c + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index b857ad6ea6..1bf6ff9e11 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -173,11 +173,22 @@ tests += \ + tst-shstk-legacy-1b-static \ + tst-shstk-legacy-1c \ + tst-shstk-legacy-1c-static \ ++ tst-shstk-legacy-1d \ ++ tst-shstk-legacy-1d-static \ ++ tst-shstk-legacy-1e \ ++ tst-shstk-legacy-1e-static \ ++ tst-shstk-legacy-1f \ ++ tst-shstk-legacy-1g \ + # tests ++modules-names += \ ++ tst-shstk-legacy-mod-1 \ ++# modules-names + tests-static += \ + tst-shstk-legacy-1a-static \ + tst-shstk-legacy-1b-static \ + tst-shstk-legacy-1c-static \ ++ tst-shstk-legacy-1d-static \ ++ tst-shstk-legacy-1e-static \ + # tests-static + extra-objs += \ + tst-shstk-legacy-1-extra.o \ +@@ -237,6 +248,9 @@ CFLAGS-tst-cet-legacy-10a-static.c += -fcf-protection=none + + CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none + CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1d.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1d-static.c += -fcf-protection=none ++CFLAGS-tst-shstk-legacy-1f.c += -fcf-protection=none + + $(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ + $(objpfx)tst-cet-legacy-mod-2.so +@@ -279,6 +293,28 @@ tst-shstk-legacy-1c-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK + tst-shstk-legacy-1c-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK + $(objpfx)tst-shstk-legacy-1c: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1c-static: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1d: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1d-static: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1e: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1e-static: $(objpfx)tst-shstk-legacy-1-extra.o ++$(objpfx)tst-shstk-legacy-1e.out: \ ++ $(..)/sysdeps/x86/tst-shstk-legacy-1e.sh $(objpfx)tst-shstk-legacy-1e ++ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \ ++ $(evaluate-test) ++$(objpfx)tst-shstk-legacy-1e-static.out: \ ++ $(..)/sysdeps/x86/tst-shstk-legacy-1e-static.sh \ ++ $(objpfx)tst-shstk-legacy-1e-static ++ $(SHELL) $< $(common-objpfx) 2> $@; \ ++ $(evaluate-test) ++$(objpfx)tst-shstk-legacy-1f: $(objpfx)tst-shstk-legacy-mod-1.so ++$(objpfx)tst-shstk-legacy-mod-1.so: \ ++ $(objpfx)tst-shstk-legacy-mod-1.os \ ++ $(objpfx)tst-shstk-legacy-1-extra.os ++$(objpfx)tst-shstk-legacy-1g: $(objpfx)tst-shstk-legacy-mod-1.so ++$(objpfx)tst-shstk-legacy-1g.out: \ ++ $(..)/sysdeps/x86/tst-shstk-legacy-1g.sh $(objpfx)tst-shstk-legacy-1g ++ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \ ++ $(evaluate-test) + endif + + # Add -fcf-protection to CFLAGS when CET is enabled. +diff --git a/sysdeps/x86/tst-shstk-legacy-1d-static.c b/sysdeps/x86/tst-shstk-legacy-1d-static.c +new file mode 100644 +index 0000000000..dca27a5482 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1d-static.c +@@ -0,0 +1 @@ ++#include "tst-shstk-legacy-1d.c" +diff --git a/sysdeps/x86/tst-shstk-legacy-1d.c b/sysdeps/x86/tst-shstk-legacy-1d.c +new file mode 100644 +index 0000000000..465cfab1db +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1d.c +@@ -0,0 +1,47 @@ ++/* Check that legacy shadow stack code in init_array won't trigger ++ segfault. ++ Copyright (C) 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 ++ ++/* Check that legacy shadow stack code in init_array won't trigger ++ segfault. */ ++extern void legacy (void); ++int done; ++ ++void ++legacy_1 (void) ++{ ++ legacy (); ++ done = 1; ++} ++ ++void (*init_array []) (void) ++ __attribute__ ((section (".init_array"), aligned (sizeof (void *)))) = ++{ ++ &legacy_1 ++}; ++ ++static int ++do_test (void) ++{ ++ return EXIT_SUCCESS; ++} ++ ++#include +diff --git a/sysdeps/x86/tst-shstk-legacy-1e-static.c b/sysdeps/x86/tst-shstk-legacy-1e-static.c +new file mode 100644 +index 0000000000..cb6ce0de00 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1e-static.c +@@ -0,0 +1 @@ ++#include "tst-shstk-legacy-1e.c" +diff --git a/sysdeps/x86/tst-shstk-legacy-1e-static.sh b/sysdeps/x86/tst-shstk-legacy-1e-static.sh +new file mode 100755 +index 0000000000..e943aec70e +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1e-static.sh +@@ -0,0 +1,32 @@ ++#!/bin/sh ++# Check that legacy shadow stack code in init_array will trigger ++# segfault. ++# Copyright (C) 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 ++# . ++ ++common_objpfx=$1; shift ++ ++${common_objpfx}elf/tst-shstk-legacy-1e-static ++# The exit status should only be unsupported (77) or segfault (139). ++status=$? ++if test $status -eq 77; then ++ exit 77 ++elif test $status == 139; then ++ exit 0 ++else ++ exit 1 ++fi +diff --git a/sysdeps/x86/tst-shstk-legacy-1e.c b/sysdeps/x86/tst-shstk-legacy-1e.c +new file mode 100644 +index 0000000000..e78a4b776e +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1e.c +@@ -0,0 +1,53 @@ ++/* Check that legacy shadow stack code in init_array will trigger ++ segfault. ++ Copyright (C) 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 ++ ++/* Check that legacy shadow stack code in init_array will trigger ++ segfault. */ ++extern void legacy (void); ++int done; ++ ++void ++legacy_1 (void) ++{ ++ legacy (); ++ done = 1; ++} ++ ++void (*init_array []) (void) ++ __attribute__ ((section (".init_array"), aligned (sizeof (void *)))) = ++{ ++ &legacy_1 ++}; ++ ++static int ++do_test (void) ++{ ++ if (!CPU_FEATURE_ACTIVE (SHSTK)) ++ return EXIT_UNSUPPORTED; ++ ++ return EXIT_FAILURE; ++} ++ ++#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (SHSTK) ? SIGSEGV : 0) ++#include +diff --git a/sysdeps/x86/tst-shstk-legacy-1e.sh b/sysdeps/x86/tst-shstk-legacy-1e.sh +new file mode 100755 +index 0000000000..b0467aa899 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1e.sh +@@ -0,0 +1,34 @@ ++#!/bin/sh ++# Check that legacy shadow stack code in init_array will trigger ++# segfault. ++# Copyright (C) 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 ++# . ++ ++common_objpfx=$1; shift ++test_program_prefix=$1; shift ++ ++${test_program_prefix} \ ++ ${common_objpfx}elf/tst-shstk-legacy-1e ++# The exit status should only be unsupported (77) or segfault (139). ++status=$? ++if test $status -eq 77; then ++ exit 77 ++elif test $status == 139; then ++ exit 0 ++else ++ exit 1 ++fi +diff --git a/sysdeps/x86/tst-shstk-legacy-1f.c b/sysdeps/x86/tst-shstk-legacy-1f.c +new file mode 100644 +index 0000000000..27e01a229e +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1f.c +@@ -0,0 +1,29 @@ ++/* Check that legacy shadow stack code in init_array won't trigger ++ segfault. ++ Copyright (C) 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 ++ ++static int ++do_test (void) ++{ ++ return EXIT_SUCCESS; ++} ++ ++#include +diff --git a/sysdeps/x86/tst-shstk-legacy-1g.c b/sysdeps/x86/tst-shstk-legacy-1g.c +new file mode 100644 +index 0000000000..a1f3d242e9 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1g.c +@@ -0,0 +1,35 @@ ++/* Check that legacy shadow stack code in init_array will trigger ++ segfault. ++ Copyright (C) 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 ++ ++static int ++do_test (void) ++{ ++ if (!CPU_FEATURE_ACTIVE (SHSTK)) ++ return EXIT_UNSUPPORTED; ++ ++ return EXIT_FAILURE; ++} ++ ++#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (SHSTK) ? SIGSEGV : 0) ++#include +diff --git a/sysdeps/x86/tst-shstk-legacy-1g.sh b/sysdeps/x86/tst-shstk-legacy-1g.sh +new file mode 100755 +index 0000000000..c112bf6d8d +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-1g.sh +@@ -0,0 +1,34 @@ ++#!/bin/sh ++# Check that legacy shadow stack code in init_array will trigger ++# segfault. ++# Copyright (C) 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 ++# . ++ ++common_objpfx=$1; shift ++test_program_prefix=$1; shift ++ ++${test_program_prefix} \ ++ ${common_objpfx}elf/tst-shstk-legacy-1g ++# The exit status should only be unsupported (77) or segfault (139). ++status=$? ++if test $status -eq 77; then ++ exit 77 ++elif test $status == 139; then ++ exit 0 ++else ++ exit 1 ++fi +diff --git a/sysdeps/x86/tst-shstk-legacy-mod-1.c b/sysdeps/x86/tst-shstk-legacy-mod-1.c +new file mode 100644 +index 0000000000..b75b5484d9 +--- /dev/null ++++ b/sysdeps/x86/tst-shstk-legacy-mod-1.c +@@ -0,0 +1,28 @@ ++/* Check legacy shadow stack code in init_array. ++ Copyright (C) 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 ++ ++/* Check legacy shadow stack code in init_array. */ ++extern void legacy (void) __attribute__ ((visibility ("hidden"))); ++ ++void (*init_array []) (void) ++ __attribute__ ((section (".init_array"), aligned (sizeof (void *)))) = ++{ ++ &legacy ++}; +-- +2.27.0 + diff --git a/x86-cet-Check-user_shstk-in-proc-cpuinfo.patch b/x86-cet-Check-user_shstk-in-proc-cpuinfo.patch new file mode 100644 index 0000000..cae8f46 --- /dev/null +++ b/x86-cet-Check-user_shstk-in-proc-cpuinfo.patch @@ -0,0 +1,29 @@ +From 27da1273b93f4068c6c61390fdc1ca0ef0b355dc Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 16 Dec 2023 08:53:10 -0800 +Subject: [PATCH] x86/cet: Check user_shstk in /proc/cpuinfo + +Linux kernel reports CPU shadow stack feature in /proc/cpuinfo as +user_shstk, instead of shstk. + +(cherry picked from commit 0b850186fd3177311f10dcb938b668cc750fa3be) +--- + sysdeps/x86/tst-cpu-features-cpuinfo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c +index 18d64375ca..1d6c647b70 100644 +--- a/sysdeps/x86/tst-cpu-features-cpuinfo.c ++++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c +@@ -246,7 +246,7 @@ do_test (int argc, char **argv) + fails += CHECK_PROC (sgx, SGX); + fails += CHECK_PROC (sgx_lc, SGX_LC); + fails += CHECK_PROC (sha_ni, SHA); +- fails += CHECK_PROC (shstk, SHSTK); ++ fails += CHECK_PROC (user_shstk, SHSTK); + fails += CHECK_PROC (smap, SMAP); + fails += CHECK_PROC (smep, SMEP); + fails += CHECK_PROC (smx, SMX); +-- +2.27.0 + diff --git a/x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch b/x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch new file mode 100644 index 0000000..9e09ba3 --- /dev/null +++ b/x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch @@ -0,0 +1,100 @@ +From f258b3fa5abb35c1a9252c1676d5c1980affc509 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 16 Dec 2023 08:53:12 -0800 +Subject: [PATCH] x86/cet: Don't assume that SHSTK implies IBT + +Since shadow stack (SHSTK) is enabled in the Linux kernel without +enabling indirect branch tracking (IBT), don't assume that SHSTK +implies IBT. Use "CPU_FEATURE_ACTIVE (IBT)" to check if IBT is active +and "CPU_FEATURE_ACTIVE (SHSTK)" to check if SHSTK is active. + +(cherry picked from commit 442983319ba70de801fc856e8dd4748fba8f7f1b) +--- + sysdeps/x86/Makefile | 1 - + sysdeps/x86/tst-cet-legacy-10.c | 6 +++--- + sysdeps/x86/tst-cet-legacy-8.c | 15 ++++++++------- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 5631a59a26..3d936ed537 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -209,7 +209,6 @@ CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=branch + CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection + CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection + CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none +-CFLAGS-tst-cet-legacy-8.c += -mshstk + CFLAGS-tst-cet-legacy-10.c += -mshstk + CFLAGS-tst-cet-legacy-10-static.c += -mshstk + +diff --git a/sysdeps/x86/tst-cet-legacy-10.c b/sysdeps/x86/tst-cet-legacy-10.c +index a85cdc3171..ae2c34de3e 100644 +--- a/sysdeps/x86/tst-cet-legacy-10.c ++++ b/sysdeps/x86/tst-cet-legacy-10.c +@@ -21,19 +21,19 @@ + #include + #include + +-/* Check that CPU_FEATURE_ACTIVE on IBT and SHSTK matches _get_ssp. */ ++/* Check that CPU_FEATURE_ACTIVE on SHSTK matches _get_ssp. */ + + static int + do_test (void) + { + if (_get_ssp () != 0) + { +- if (CPU_FEATURE_ACTIVE (IBT) && CPU_FEATURE_ACTIVE (SHSTK)) ++ if (CPU_FEATURE_ACTIVE (SHSTK)) + return EXIT_SUCCESS; + } + else + { +- if (!CPU_FEATURE_ACTIVE (IBT) && !CPU_FEATURE_ACTIVE (SHSTK)) ++ if (!CPU_FEATURE_ACTIVE (SHSTK)) + return EXIT_SUCCESS; + } + +diff --git a/sysdeps/x86/tst-cet-legacy-8.c b/sysdeps/x86/tst-cet-legacy-8.c +index 5d8d9ba7dc..77d77a5408 100644 +--- a/sysdeps/x86/tst-cet-legacy-8.c ++++ b/sysdeps/x86/tst-cet-legacy-8.c +@@ -18,7 +18,7 @@ + + #include + #include +-#include ++#include + #include + #include + #include +@@ -29,11 +29,6 @@ + static int + do_test (void) + { +- /* NB: This test should trigger SIGSEGV on CET platforms. If SHSTK +- is disabled, assuming IBT is also disabled. */ +- if (_get_ssp () == 0) +- return EXIT_UNSUPPORTED; +- + void (*funcp) (void); + funcp = xmmap (NULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1); +@@ -41,8 +36,14 @@ do_test (void) + /* Write RET instruction. */ + *(char *) funcp = 0xc3; + funcp (); ++ ++ /* NB: This test should trigger SIGSEGV when IBT is active. We should ++ reach here if IBT isn't active. */ ++ if (!CPU_FEATURE_ACTIVE (IBT)) ++ return EXIT_UNSUPPORTED; ++ + return EXIT_FAILURE; + } + +-#define EXPECTED_SIGNAL (_get_ssp () == 0 ? 0 : SIGSEGV) ++#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (IBT) ? SIGSEGV : 0) + #include +-- +2.27.0 + diff --git a/x86-cet-Don-t-disable-CET-if-not-single-threaded.patch b/x86-cet-Don-t-disable-CET-if-not-single-threaded.patch new file mode 100644 index 0000000..5271394 --- /dev/null +++ b/x86-cet-Don-t-disable-CET-if-not-single-threaded.patch @@ -0,0 +1,55 @@ +From 9397174e482f9266bc77dd057789f46ea0dd5eac Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 28 Jul 2023 14:06:01 -0700 +Subject: [PATCH] x86/cet: Don't disable CET if not single threaded + +In permissive mode, don't disable IBT nor SHSTK when dlopening a legacy +shared library if not single threaded since IBT and SHSTK may be still +enabled in other threads. Other threads with IBT or SHSTK enabled will +crash when calling functions in the legacy shared library. Instead, an +error will be issued. + +(cherry picked from commit 41560a9312ce0ec7203480eef8f865076bff9edb) +--- + sysdeps/x86/dl-cet.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c +index 67c51ee8c2..e486e549be 100644 +--- a/sysdeps/x86/dl-cet.c ++++ b/sysdeps/x86/dl-cet.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + /* GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK + are defined in , which are only available for C sources. +@@ -233,7 +234,10 @@ dl_cet_check_dlopen (struct link_map *m, struct dl_cet_info *info) + && (info->feature_1_legacy + & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0) + { +- if (info->enable_ibt_type != cet_permissive) ++ /* Don't disable IBT if not single threaded since IBT may be still ++ enabled in other threads. */ ++ if (info->enable_ibt_type != cet_permissive ++ || !SINGLE_THREAD_P) + { + legacy_obj = info->feature_1_legacy_ibt; + msg = N_("rebuild shared object with IBT support enabled"); +@@ -249,7 +253,10 @@ dl_cet_check_dlopen (struct link_map *m, struct dl_cet_info *info) + && (info->feature_1_legacy + & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0) + { +- if (info->enable_shstk_type != cet_permissive) ++ /* Don't disable SHSTK if not single threaded since SHSTK may be ++ still enabled in other threads. */ ++ if (info->enable_shstk_type != cet_permissive ++ || !SINGLE_THREAD_P) + { + legacy_obj = info->feature_1_legacy_shstk; + msg = N_("rebuild shared object with SHSTK support enabled"); +-- +2.27.0 + diff --git a/x86-cet-Don-t-set-CET-active-by-default.patch b/x86-cet-Don-t-set-CET-active-by-default.patch new file mode 100644 index 0000000..1f2e21b --- /dev/null +++ b/x86-cet-Don-t-set-CET-active-by-default.patch @@ -0,0 +1,78 @@ +From 0d1abcab552707e8fc069dbc8658ae7ff7295022 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 29 Dec 2023 08:43:53 -0800 +Subject: [PATCH] x86/cet: Don't set CET active by default + +Not all CET enabled applications and libraries have been properly tested +in CET enabled environments. Some CET enabled applications or libraries +will crash or misbehave when CET is enabled. Don't set CET active by +default so that all applications and libraries will run normally regardless +of whether CET is active or not. Shadow stack can be enabled by + +$ export GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK + +at run-time if shadow stack can be enabled by kernel. + +NB: This commit can be reverted if it is OK to enable CET by default for +all applications and libraries. + +(cherry picked from commit 55d63e731253de82e96ed4ddca2e294076cd0bc5) +--- + sysdeps/x86/cpu-features.c | 2 +- + sysdeps/x86/cpu-tunables.c | 16 +++++++++++++++- + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index c9132dbe2d..87845e9fe8 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -110,7 +110,7 @@ update_active (struct cpu_features *cpu_features) + if (!CPU_FEATURES_CPU_P (cpu_features, RTM_ALWAYS_ABORT)) + CPU_FEATURE_SET_ACTIVE (cpu_features, RTM); + +-#if CET_ENABLED ++#if CET_ENABLED && 0 + CPU_FEATURE_SET_ACTIVE (cpu_features, IBT); + CPU_FEATURE_SET_ACTIVE (cpu_features, SHSTK); + #endif +diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c +index 0d4f328585..c144124142 100644 +--- a/sysdeps/x86/cpu-tunables.c ++++ b/sysdeps/x86/cpu-tunables.c +@@ -47,6 +47,17 @@ extern __typeof (memcmp) DEFAULT_MEMCMP; + break; \ + } + ++#define CHECK_GLIBC_IFUNC_CPU_BOTH(f, cpu_features, name, disable, len) \ ++ _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \ ++ if (!DEFAULT_MEMCMP (f, #name, len)) \ ++ { \ ++ if (disable) \ ++ CPU_FEATURE_UNSET (cpu_features, name) \ ++ else \ ++ CPU_FEATURE_SET_ACTIVE (cpu_features, name) \ ++ break; \ ++ } ++ + /* Disable a preferred feature NAME. We don't enable a preferred feature + which isn't available. */ + #define CHECK_GLIBC_IFUNC_PREFERRED_OFF(f, cpu_features, name, len) \ +@@ -162,11 +173,14 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + } + break; + case 5: ++ { ++ CHECK_GLIBC_IFUNC_CPU_BOTH (n, cpu_features, SHSTK, disable, ++ 5); ++ } + if (disable) + { + CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, LZCNT, 5); + CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, MOVBE, 5); +- CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SHSTK, 5); + CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SSSE3, 5); + CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, XSAVE, 5); + } +-- +2.27.0 + diff --git a/x86-cet-Enable-shadow-stack-during-startup.patch b/x86-cet-Enable-shadow-stack-during-startup.patch new file mode 100644 index 0000000..1dce7cd --- /dev/null +++ b/x86-cet-Enable-shadow-stack-during-startup.patch @@ -0,0 +1,512 @@ +From 5f6e2a06f6a4b03ff192399f909b26d1d395df4a Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 29 Dec 2023 08:43:51 -0800 +Subject: [PATCH] x86/cet: Enable shadow stack during startup + +Previously, CET was enabled by kernel before passing control to user +space and the startup code must disable CET if applications or shared +libraries aren't CET enabled. Since the current kernel only supports +shadow stack and won't enable shadow stack before passing control to +user space, we need to enable shadow stack during startup if the +application and all shared library are shadow stack enabled. There +is no need to disable shadow stack at startup. Shadow stack can only +be enabled in a function which will never return. Otherwise, shadow +stack will underflow at the function return. + +1. GL(dl_x86_feature_1) is set to the CET features which are supported +by the processor and are not disabled by the tunable. Only non-zero +features in GL(dl_x86_feature_1) should be enabled. After enabling +shadow stack with ARCH_SHSTK_ENABLE, ARCH_SHSTK_STATUS is used to check +if shadow stack is really enabled. +2. Use ARCH_SHSTK_ENABLE in RTLD_START in dynamic executable. It is +safe since RTLD_START never returns. +3. Call arch_prctl (ARCH_SHSTK_ENABLE) from ARCH_SETUP_TLS in static +executable. Since the start function using ARCH_SETUP_TLS never returns, +it is safe to enable shadow stack in ARCH_SETUP_TLS. + +(cherry picked from commit 541641a3de8d89464151bd879552755e882c832e) +--- + sysdeps/unix/sysv/linux/x86/cpu-features.c | 49 -------------- + sysdeps/unix/sysv/linux/x86/dl-cet.h | 27 +++++++- + sysdeps/unix/sysv/linux/x86_64/dl-cet.h | 47 +++++++++++++ + sysdeps/x86/cpu-features-offsets.sym | 1 + + sysdeps/x86/cpu-features.c | 51 --------------- + sysdeps/x86/dl-cet.c | 76 +++++++++++----------- + sysdeps/x86/get-cpuid-feature-leaf.c | 2 +- + sysdeps/x86/include/cpu-features.h | 3 + + sysdeps/x86/libc-start.h | 53 ++++++++++++++- + sysdeps/x86_64/dl-machine.h | 12 +++- + 10 files changed, 175 insertions(+), 146 deletions(-) + delete mode 100644 sysdeps/unix/sysv/linux/x86/cpu-features.c + create mode 100644 sysdeps/unix/sysv/linux/x86_64/dl-cet.h + +diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c +deleted file mode 100644 +index 0e6e2bf855..0000000000 +--- a/sysdeps/unix/sysv/linux/x86/cpu-features.c ++++ /dev/null +@@ -1,49 +0,0 @@ +-/* Initialize CPU feature data for Linux/x86. +- This file is part of the GNU C Library. +- Copyright (C) 2018-2023 Free Software Foundation, Inc. +- +- 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 +- . */ +- +-#if CET_ENABLED +-# include +-# include +- +-static inline int __attribute__ ((always_inline)) +-get_cet_status (void) +-{ +- unsigned long long kernel_feature; +- unsigned int status = 0; +- if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS, +- &kernel_feature) == 0) +- { +- if ((kernel_feature & ARCH_SHSTK_SHSTK) != 0) +- status = GNU_PROPERTY_X86_FEATURE_1_SHSTK; +- } +- return status; +-} +- +-# ifndef SHARED +-static inline void +-x86_setup_tls (void) +-{ +- __libc_setup_tls (); +- THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)); +-} +- +-# define ARCH_SETUP_TLS() x86_setup_tls () +-# endif +-#endif +- +-#include +diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h +index da220ac627..6ad5e03f69 100644 +--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h +@@ -18,7 +18,7 @@ + #include + #include + +-static inline int __attribute__ ((always_inline)) ++static __always_inline int + dl_cet_disable_cet (unsigned int cet_feature) + { + if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) +@@ -28,7 +28,7 @@ dl_cet_disable_cet (unsigned int cet_feature) + kernel_feature); + } + +-static inline int __attribute__ ((always_inline)) ++static __always_inline int + dl_cet_lock_cet (unsigned int cet_feature) + { + if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) +@@ -38,3 +38,26 @@ dl_cet_lock_cet (unsigned int cet_feature) + return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK, + kernel_feature); + } ++ ++static __always_inline unsigned int ++dl_cet_get_cet_status (void) ++{ ++ unsigned long long kernel_feature; ++ unsigned int status = 0; ++ if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS, ++ &kernel_feature) == 0) ++ { ++ if ((kernel_feature & ARCH_SHSTK_SHSTK) != 0) ++ status = GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ } ++ return status; ++} ++ ++/* Enable shadow stack with a macro to avoid shadow stack underflow. */ ++#define ENABLE_X86_CET(cet_feature) \ ++ if ((cet_feature & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) \ ++ { \ ++ long long int kernel_feature = ARCH_SHSTK_SHSTK; \ ++ INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_ENABLE, \ ++ kernel_feature); \ ++ } +diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +new file mode 100644 +index 0000000000..e23e05c6b8 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +@@ -0,0 +1,47 @@ ++/* Linux/x86-64 CET initializers function. ++ Copyright (C) 2023 Free Software Foundation, Inc. ++ ++ 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_next ++ ++#define X86_STRINGIFY_1(x) #x ++#define X86_STRINGIFY(x) X86_STRINGIFY_1 (x) ++ ++/* Enable shadow stack before calling _dl_init if it is enabled in ++ GL(dl_x86_feature_1). Call _dl_setup_x86_features to setup shadow ++ stack. */ ++#define RTLD_START_ENABLE_X86_FEATURES \ ++"\ ++ # Check if shadow stack is enabled in GL(dl_x86_feature_1).\n\ ++ movl _rtld_local+" X86_STRINGIFY (RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET) "(%rip), %edx\n\ ++ testl $" X86_STRINGIFY (X86_FEATURE_1_SHSTK) ", %edx\n\ ++ jz 1f\n\ ++ # Enable shadow stack if enabled in GL(dl_x86_feature_1).\n\ ++ movl $" X86_STRINGIFY (ARCH_SHSTK_SHSTK) ", %esi\n\ ++ movl $" X86_STRINGIFY (ARCH_SHSTK_ENABLE) ", %edi\n\ ++ movl $" X86_STRINGIFY (__NR_arch_prctl) ", %eax\n\ ++ syscall\n\ ++1:\n\ ++ # Pass GL(dl_x86_feature_1) to _dl_cet_setup_features.\n\ ++ movl %edx, %edi\n\ ++ # Align stack for the _dl_cet_setup_features call.\n\ ++ andq $-16, %rsp\n\ ++ call _dl_cet_setup_features\n\ ++ # Restore %rax and %rsp from %r12 and %r13.\n\ ++ movq %r12, %rax\n\ ++ movq %r13, %rsp\n\ ++" +diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym +index 6d03cea8e8..5429f60632 100644 +--- a/sysdeps/x86/cpu-features-offsets.sym ++++ b/sysdeps/x86/cpu-features-offsets.sym +@@ -4,3 +4,4 @@ + + RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET offsetof (struct rtld_global_ro, _dl_x86_cpu_features) + XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size) ++RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET offsetof (struct rtld_global, _dl_x86_feature_1) +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index 61d3ca38f8..c9132dbe2d 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -1081,57 +1081,6 @@ no_cpuid: + TUNABLE_CALLBACK (set_x86_ibt)); + TUNABLE_GET (x86_shstk, tunable_val_t *, + TUNABLE_CALLBACK (set_x86_shstk)); +- +- /* Check CET status. */ +- unsigned int cet_status = get_cet_status (); +- +- if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT) == 0) +- CPU_FEATURE_UNSET (cpu_features, IBT) +- if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK) == 0) +- CPU_FEATURE_UNSET (cpu_features, SHSTK) +- +- if (cet_status) +- { +- GL(dl_x86_feature_1) = cet_status; +- +-# ifndef SHARED +- /* Check if IBT and SHSTK are enabled by kernel. */ +- if ((cet_status +- & (GNU_PROPERTY_X86_FEATURE_1_IBT +- | GNU_PROPERTY_X86_FEATURE_1_SHSTK))) +- { +- /* Disable IBT and/or SHSTK if they are enabled by kernel, but +- disabled by environment variable: +- +- GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK +- */ +- unsigned int cet_feature = 0; +- if (!CPU_FEATURE_USABLE (IBT)) +- cet_feature |= (cet_status +- & GNU_PROPERTY_X86_FEATURE_1_IBT); +- if (!CPU_FEATURE_USABLE (SHSTK)) +- cet_feature |= (cet_status +- & GNU_PROPERTY_X86_FEATURE_1_SHSTK); +- +- if (cet_feature) +- { +- int res = dl_cet_disable_cet (cet_feature); +- +- /* Clear the disabled bits in dl_x86_feature_1. */ +- if (res == 0) +- GL(dl_x86_feature_1) &= ~cet_feature; +- } +- +- /* Lock CET if IBT or SHSTK is enabled in executable. Don't +- lock CET if IBT or SHSTK is enabled permissively. */ +- if (GL(dl_x86_feature_control).ibt != cet_permissive +- && GL(dl_x86_feature_control).shstk != cet_permissive) +- dl_cet_lock_cet (GL(dl_x86_feature_1) +- & (GNU_PROPERTY_X86_FEATURE_1_IBT +- | GNU_PROPERTY_X86_FEATURE_1_SHSTK)); +- } +-# endif +- } + #endif + + #ifndef SHARED +diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c +index 66a78244d4..82167ebf50 100644 +--- a/sysdeps/x86/dl-cet.c ++++ b/sysdeps/x86/dl-cet.c +@@ -173,40 +173,11 @@ dl_cet_check_startup (struct link_map *m, struct dl_cet_info *info) + = info->enable_feature_1 ^ info->feature_1_enabled; + if (disable_feature_1 != 0) + { +- /* Disable features in the kernel because of legacy objects or +- cet_always_off. */ +- if (dl_cet_disable_cet (disable_feature_1) != 0) +- _dl_fatal_printf ("%s: can't disable x86 Features\n", +- info->program); +- + /* Clear the disabled bits. Sync dl_x86_feature_1 and + info->feature_1_enabled with info->enable_feature_1. */ + info->feature_1_enabled = info->enable_feature_1; + GL(dl_x86_feature_1) = info->enable_feature_1; + } +- +- if (HAS_CPU_FEATURE (IBT) || HAS_CPU_FEATURE (SHSTK)) +- { +- /* Lock CET features only if IBT or SHSTK are enabled and are not +- enabled permissively. */ +- unsigned int feature_1_lock = 0; +- +- if (((info->feature_1_enabled & GNU_PROPERTY_X86_FEATURE_1_IBT) +- != 0) +- && info->enable_ibt_type != cet_permissive) +- feature_1_lock |= GNU_PROPERTY_X86_FEATURE_1_IBT; +- +- if (((info->feature_1_enabled & GNU_PROPERTY_X86_FEATURE_1_SHSTK) +- != 0) +- && info->enable_shstk_type != cet_permissive) +- feature_1_lock |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; +- +- if (feature_1_lock != 0 +- && dl_cet_lock_cet (feature_1_lock) != 0) +- _dl_fatal_printf ("%s: can't lock CET\n", info->program); +- } +- +- THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)); + } + #endif + +@@ -298,6 +269,15 @@ dl_cet_check (struct link_map *m, const char *program) + { + struct dl_cet_info info; + ++ /* CET is enabled only if RTLD_START_ENABLE_X86_FEATURES is defined. */ ++#if defined SHARED && defined RTLD_START_ENABLE_X86_FEATURES ++ /* Set dl_x86_feature_1 to features enabled in the executable. */ ++ if (program != NULL) ++ GL(dl_x86_feature_1) = (m->l_x86_feature_1_and ++ & (X86_FEATURE_1_IBT ++ | X86_FEATURE_1_SHSTK)); ++#endif ++ + /* Check how IBT and SHSTK should be enabled. */ + info.enable_ibt_type = GL(dl_x86_feature_control).ibt; + info.enable_shstk_type = GL(dl_x86_feature_control).shstk; +@@ -307,17 +287,9 @@ dl_cet_check (struct link_map *m, const char *program) + /* No legacy object check if IBT and SHSTK are always on. */ + if (info.enable_ibt_type == cet_always_on + && info.enable_shstk_type == cet_always_on) +- { +-#ifdef SHARED +- /* Set it only during startup. */ +- if (program != NULL) +- THREAD_SETMEM (THREAD_SELF, header.feature_1, +- info.feature_1_enabled); +-#endif +- return; +- } ++ return; + +- /* Check if IBT and SHSTK were enabled by kernel. */ ++ /* Check if IBT and SHSTK were enabled. */ + if (info.feature_1_enabled == 0) + return; + +@@ -351,6 +323,32 @@ _dl_cet_open_check (struct link_map *l) + dl_cet_check (l, NULL); + } + ++/* Set GL(dl_x86_feature_1) to the enabled features and clear the ++ active bits of the disabled features. */ ++ ++attribute_hidden void ++_dl_cet_setup_features (unsigned int cet_feature) ++{ ++ /* NB: cet_feature == GL(dl_x86_feature_1) which is set to features ++ enabled from executable, not necessarily supported by kernel. */ ++ if (cet_feature != 0) ++ { ++ cet_feature = dl_cet_get_cet_status (); ++ if (cet_feature != 0) ++ { ++ THREAD_SETMEM (THREAD_SELF, header.feature_1, cet_feature); ++ ++ /* Lock CET if IBT or SHSTK is enabled in executable. Don't ++ lock CET if IBT or SHSTK is enabled permissively. */ ++ if (GL(dl_x86_feature_control).ibt != cet_permissive ++ && (GL(dl_x86_feature_control).shstk != cet_permissive)) ++ dl_cet_lock_cet (cet_feature); ++ } ++ /* Sync GL(dl_x86_feature_1) with kernel. */ ++ GL(dl_x86_feature_1) = cet_feature; ++ } ++} ++ + #ifdef SHARED + + # ifndef LINKAGE +diff --git a/sysdeps/x86/get-cpuid-feature-leaf.c b/sysdeps/x86/get-cpuid-feature-leaf.c +index 40a46cc79c..9317a6b494 100644 +--- a/sysdeps/x86/get-cpuid-feature-leaf.c ++++ b/sysdeps/x86/get-cpuid-feature-leaf.c +@@ -24,7 +24,7 @@ __x86_get_cpuid_feature_leaf (unsigned int leaf) + static const struct cpuid_feature feature = {}; + if (leaf < CPUID_INDEX_MAX) + return ((const struct cpuid_feature *) +- &GLRO(dl_x86_cpu_features).features[leaf]); ++ &GLRO(dl_x86_cpu_features).features[leaf]); + else + return &feature; + } +diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h +index eb30d342a6..2dfab74941 100644 +--- a/sysdeps/x86/include/cpu-features.h ++++ b/sysdeps/x86/include/cpu-features.h +@@ -965,6 +965,9 @@ extern const struct cpu_features *_dl_x86_get_cpu_features (void) + # define INIT_ARCH() + # define _dl_x86_get_cpu_features() (&GLRO(dl_x86_cpu_features)) + extern void _dl_x86_init_cpu_features (void) attribute_hidden; ++ ++extern void _dl_cet_setup_features (unsigned int) ++ attribute_hidden; + #endif + + #ifdef __x86_64__ +diff --git a/sysdeps/x86/libc-start.h b/sysdeps/x86/libc-start.h +index e93da6ef3d..7a91dd192a 100644 +--- a/sysdeps/x86/libc-start.h ++++ b/sysdeps/x86/libc-start.h +@@ -19,7 +19,56 @@ + #ifndef SHARED + # define ARCH_SETUP_IREL() apply_irel () + # define ARCH_APPLY_IREL() +-# ifndef ARCH_SETUP_TLS +-# define ARCH_SETUP_TLS() __libc_setup_tls () ++# ifdef __CET__ ++/* Get CET features enabled in the static executable. */ ++ ++static inline unsigned int ++get_cet_feature (void) ++{ ++ /* Check if CET is supported and not disabled by tunables. */ ++ const struct cpu_features *cpu_features = __get_cpu_features (); ++ unsigned int cet_feature = 0; ++ if (CPU_FEATURE_USABLE_P (cpu_features, IBT)) ++ cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT; ++ if (CPU_FEATURE_USABLE_P (cpu_features, SHSTK)) ++ cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ if (!cet_feature) ++ return cet_feature; ++ ++ struct link_map *main_map = _dl_get_dl_main_map (); ++ ++ /* Scan program headers backward to check PT_GNU_PROPERTY early for ++ x86 feature bits on static executable. */ ++ const ElfW(Phdr) *phdr = GL(dl_phdr); ++ const ElfW(Phdr) *ph; ++ for (ph = phdr + GL(dl_phnum); ph != phdr; ph--) ++ if (ph[-1].p_type == PT_GNU_PROPERTY) ++ { ++ _dl_process_pt_gnu_property (main_map, -1, &ph[-1]); ++ /* Enable IBT and SHSTK only if they are enabled on static ++ executable. */ ++ cet_feature &= (main_map->l_x86_feature_1_and ++ & (GNU_PROPERTY_X86_FEATURE_1_IBT ++ | GNU_PROPERTY_X86_FEATURE_1_SHSTK)); ++ /* Set GL(dl_x86_feature_1) to the enabled CET features. */ ++ GL(dl_x86_feature_1) = cet_feature; ++ break; ++ } ++ ++ return cet_feature; ++} ++ ++/* The function using this macro to enable shadow stack must not return ++ to avoid shadow stack underflow. */ ++# define ARCH_SETUP_TLS() \ ++ { \ ++ __libc_setup_tls (); \ ++ \ ++ unsigned int cet_feature = get_cet_feature (); \ ++ ENABLE_X86_CET (cet_feature); \ ++ _dl_cet_setup_features (cet_feature); \ ++ } ++# else ++# define ARCH_SETUP_TLS() __libc_setup_tls () + # endif + #endif /* !SHARED */ +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index 9ea2a70837..b4159880f3 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -29,6 +29,11 @@ + #include + #include + #include ++#ifdef __CET__ ++# include ++#else ++# define RTLD_START_ENABLE_X86_FEATURES ++#endif + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -144,13 +149,16 @@ _start:\n\ + _dl_start_user:\n\ + # Save the user entry point address in %r12.\n\ + movq %rax, %r12\n\ ++ # Save %rsp value in %r13.\n\ ++ movq %rsp, %r13\n\ ++"\ ++ RTLD_START_ENABLE_X86_FEATURES \ ++"\ + # Read the original argument count.\n\ + movq (%rsp), %rdx\n\ + # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\ + # argc -> rsi\n\ + movq %rdx, %rsi\n\ +- # Save %rsp value in %r13.\n\ +- movq %rsp, %r13\n\ + # And align stack for the _dl_init call. \n\ + andq $-16, %rsp\n\ + # _dl_loaded -> rdi\n\ +-- +2.27.0 + diff --git a/x86-cet-Run-some-CET-tests-with-shadow-stack.patch b/x86-cet-Run-some-CET-tests-with-shadow-stack.patch new file mode 100644 index 0000000..e668061 --- /dev/null +++ b/x86-cet-Run-some-CET-tests-with-shadow-stack.patch @@ -0,0 +1,104 @@ +From e053e7caafa1c25de3daeb5e14d33a79c7348c4c Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 29 Dec 2023 08:43:54 -0800 +Subject: [PATCH] x86/cet: Run some CET tests with shadow stack + +When CET is disabled by default, run some CET tests with shadow stack +enabled using + +$ export GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK + +(cherry picked from commit cf9481724bcb86ad4a86cca7befed74bb9cc15eb) +--- + sysdeps/x86/Makefile | 14 ++++++++++++++ + sysdeps/x86/tst-shstk-legacy-1e-static.sh | 1 + + sysdeps/x86/tst-shstk-legacy-1e.sh | 1 + + sysdeps/x86/tst-shstk-legacy-1g.sh | 1 + + 4 files changed, 17 insertions(+) + +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 6911a07a87..d751eaedf4 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -247,6 +247,13 @@ CFLAGS-tst-cet-legacy-10-static.c += -mshstk + CFLAGS-tst-cet-legacy-10a.c += -fcf-protection=none + CFLAGS-tst-cet-legacy-10a-static.c += -fcf-protection=none + ++tst-cet-legacy-4-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-6-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-cet-legacy-10a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++ + CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none + CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none + CFLAGS-tst-shstk-legacy-1d.c += -fcf-protection=none +@@ -286,14 +293,20 @@ tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK + tst-cet-legacy-9-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK + tst-cet-legacy-9-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK + ++tst-shstk-legacy-1a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-shstk-legacy-1a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK + $(objpfx)tst-shstk-legacy-1a: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1a-static: $(objpfx)tst-shstk-legacy-1-extra.o ++tst-shstk-legacy-1b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-shstk-legacy-1b-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK + $(objpfx)tst-shstk-legacy-1b: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1b-static: $(objpfx)tst-shstk-legacy-1-extra.o + tst-shstk-legacy-1c-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK + tst-shstk-legacy-1c-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK + $(objpfx)tst-shstk-legacy-1c: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1c-static: $(objpfx)tst-shstk-legacy-1-extra.o ++tst-shstk-legacy-1d-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK ++tst-shstk-legacy-1d-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK + $(objpfx)tst-shstk-legacy-1d: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1d-static: $(objpfx)tst-shstk-legacy-1-extra.o + $(objpfx)tst-shstk-legacy-1e: $(objpfx)tst-shstk-legacy-1-extra.o +@@ -307,6 +320,7 @@ $(objpfx)tst-shstk-legacy-1e-static.out: \ + $(objpfx)tst-shstk-legacy-1e-static + $(SHELL) $< $(common-objpfx) 2> $@; \ + $(evaluate-test) ++tst-shstk-legacy-1f-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK + $(objpfx)tst-shstk-legacy-1f: $(objpfx)tst-shstk-legacy-mod-1.so + $(objpfx)tst-shstk-legacy-mod-1.so: \ + $(objpfx)tst-shstk-legacy-mod-1.os \ +diff --git a/sysdeps/x86/tst-shstk-legacy-1e-static.sh b/sysdeps/x86/tst-shstk-legacy-1e-static.sh +index e943aec70e..008c50dae3 100755 +--- a/sysdeps/x86/tst-shstk-legacy-1e-static.sh ++++ b/sysdeps/x86/tst-shstk-legacy-1e-static.sh +@@ -20,6 +20,7 @@ + + common_objpfx=$1; shift + ++GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK \ + ${common_objpfx}elf/tst-shstk-legacy-1e-static + # The exit status should only be unsupported (77) or segfault (139). + status=$? +diff --git a/sysdeps/x86/tst-shstk-legacy-1e.sh b/sysdeps/x86/tst-shstk-legacy-1e.sh +index b0467aa899..82f2acbf75 100755 +--- a/sysdeps/x86/tst-shstk-legacy-1e.sh ++++ b/sysdeps/x86/tst-shstk-legacy-1e.sh +@@ -21,6 +21,7 @@ + common_objpfx=$1; shift + test_program_prefix=$1; shift + ++GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK \ + ${test_program_prefix} \ + ${common_objpfx}elf/tst-shstk-legacy-1e + # The exit status should only be unsupported (77) or segfault (139). +diff --git a/sysdeps/x86/tst-shstk-legacy-1g.sh b/sysdeps/x86/tst-shstk-legacy-1g.sh +index c112bf6d8d..261eef7cac 100755 +--- a/sysdeps/x86/tst-shstk-legacy-1g.sh ++++ b/sysdeps/x86/tst-shstk-legacy-1g.sh +@@ -21,6 +21,7 @@ + common_objpfx=$1; shift + test_program_prefix=$1; shift + ++GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK \ + ${test_program_prefix} \ + ${common_objpfx}elf/tst-shstk-legacy-1g + # The exit status should only be unsupported (77) or segfault (139). +-- +2.27.0 + diff --git a/x86-cet-Sync-with-Linux-kernel-6.6-shadow-stack-inte.patch b/x86-cet-Sync-with-Linux-kernel-6.6-shadow-stack-inte.patch new file mode 100644 index 0000000..a3ac7ee --- /dev/null +++ b/x86-cet-Sync-with-Linux-kernel-6.6-shadow-stack-inte.patch @@ -0,0 +1,577 @@ +From 99fd1f64542ef0af985951319142896bf88fdd02 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 29 Dec 2023 08:43:49 -0800 +Subject: [PATCH] x86/cet: Sync with Linux kernel 6.6 shadow stack + interface + +Sync with Linux kernel 6.6 shadow stack interface. Since only x86-64 is +supported, i386 shadow stack codes are unchanged and CET shouldn't be +enabled for i386. + +1. When the shadow stack base in TCB is unset, the default shadow stack +is in use. Use the current shadow stack pointer as the marker for the +default shadow stack. It is used to identify if the current shadow stack +is the same as the target shadow stack when switching ucontexts. If yes, +INCSSP will be used to unwind shadow stack. Otherwise, shadow stack +restore token will be used. +2. Allocate shadow stack with the map_shadow_stack syscall. Since there +is no function to explicitly release ucontext, there is no place to +release shadow stack allocated by map_shadow_stack in ucontext functions. +Such shadow stacks will be leaked. +3. Rename arch_prctl CET commands to ARCH_SHSTK_XXX. +4. Rewrite the CET control functions with the current kernel shadow stack +interface. + +Since CET is no longer enabled by kernel, a separate patch will enable +shadow stack during startup. + +(cherry picked from commit edb5e0c8f915a798629717b5680a852c8bb3db25) +--- + sysdeps/unix/sysv/linux/x86/bits/mman.h | 5 ++ + sysdeps/unix/sysv/linux/x86/cpu-features.c | 13 +++-- + sysdeps/unix/sysv/linux/x86/dl-cet.h | 16 ++++-- + .../unix/sysv/linux/x86/include/asm/prctl.h | 37 ++++++------- + .../sysv/linux/x86/tst-cet-setcontext-1.c | 17 +++--- + sysdeps/unix/sysv/linux/x86_64/Makefile | 2 +- + .../unix/sysv/linux/x86_64/__start_context.S | 38 +++---------- + .../sysv/linux/x86_64/allocate-shadow-stack.c | 55 +++++++++++++++++++ + .../sysv/linux/x86_64/allocate-shadow-stack.h | 24 ++++++++ + sysdeps/unix/sysv/linux/x86_64/getcontext.S | 30 ++-------- + sysdeps/unix/sysv/linux/x86_64/makecontext.c | 28 +++++----- + sysdeps/unix/sysv/linux/x86_64/swapcontext.S | 22 ++------ + sysdeps/x86/cpu-features.c | 15 +++-- + sysdeps/x86/dl-cet.c | 2 +- + sysdeps/x86_64/nptl/tls.h | 2 +- + 15 files changed, 173 insertions(+), 133 deletions(-) + create mode 100644 sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.c + create mode 100644 sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.h + +diff --git a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix/sysv/linux/x86/bits/mman.h +index b335ceff43..98ac7177bd 100644 +--- a/sysdeps/unix/sysv/linux/x86/bits/mman.h ++++ b/sysdeps/unix/sysv/linux/x86/bits/mman.h +@@ -26,6 +26,11 @@ + /* Other flags. */ + #define MAP_32BIT 0x40 /* Only give out 32-bit addresses. */ + ++#ifdef __USE_MISC ++/* Set up a restore token in the newly allocated shadow stack */ ++# define SHADOW_STACK_SET_TOKEN 0x1 ++#endif ++ + #include + + /* Include generic Linux declarations. */ +diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c +index 41e7600668..0e6e2bf855 100644 +--- a/sysdeps/unix/sysv/linux/x86/cpu-features.c ++++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c +@@ -23,10 +23,15 @@ + static inline int __attribute__ ((always_inline)) + get_cet_status (void) + { +- unsigned long long cet_status[3]; +- if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_STATUS, cet_status) == 0) +- return cet_status[0]; +- return 0; ++ unsigned long long kernel_feature; ++ unsigned int status = 0; ++ if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS, ++ &kernel_feature) == 0) ++ { ++ if ((kernel_feature & ARCH_SHSTK_SHSTK) != 0) ++ status = GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ } ++ return status; + } + + # ifndef SHARED +diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h +index c885bf1323..da220ac627 100644 +--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h +@@ -21,12 +21,20 @@ + static inline int __attribute__ ((always_inline)) + dl_cet_disable_cet (unsigned int cet_feature) + { +- return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_DISABLE, +- cet_feature); ++ if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ return -1; ++ long long int kernel_feature = ARCH_SHSTK_SHSTK; ++ return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_DISABLE, ++ kernel_feature); + } + + static inline int __attribute__ ((always_inline)) +-dl_cet_lock_cet (void) ++dl_cet_lock_cet (unsigned int cet_feature) + { +- return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_LOCK, 0); ++ if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK) ++ return -1; ++ /* Lock all SHSTK features. */ ++ long long int kernel_feature = -1; ++ return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK, ++ kernel_feature); + } +diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h +index 45ad0b052f..2f511321ad 100644 +--- a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h ++++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h +@@ -4,24 +4,19 @@ + + #include_next + +-#ifndef ARCH_CET_STATUS +-/* CET features: +- IBT: GNU_PROPERTY_X86_FEATURE_1_IBT +- SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK +- */ +-/* Return CET features in unsigned long long *addr: +- features: addr[0]. +- shadow stack base address: addr[1]. +- shadow stack size: addr[2]. +- */ +-# define ARCH_CET_STATUS 0x3001 +-/* Disable CET features in unsigned int features. */ +-# define ARCH_CET_DISABLE 0x3002 +-/* Lock all CET features. */ +-# define ARCH_CET_LOCK 0x3003 +-/* Allocate a new shadow stack with unsigned long long *addr: +- IN: requested shadow stack size: *addr. +- OUT: allocated shadow stack address: *addr. +- */ +-# define ARCH_CET_ALLOC_SHSTK 0x3004 +-#endif /* ARCH_CET_STATUS */ ++#ifndef ARCH_SHSTK_ENABLE ++/* Enable SHSTK features in unsigned long int features. */ ++# define ARCH_SHSTK_ENABLE 0x5001 ++/* Disable SHSTK features in unsigned long int features. */ ++# define ARCH_SHSTK_DISABLE 0x5002 ++/* Lock SHSTK features in unsigned long int features. */ ++# define ARCH_SHSTK_LOCK 0x5003 ++/* Unlock SHSTK features in unsigned long int features. */ ++# define ARCH_SHSTK_UNLOCK 0x5004 ++/* Return SHSTK features in unsigned long int features. */ ++# define ARCH_SHSTK_STATUS 0x5005 ++ ++/* ARCH_SHSTK_ features bits */ ++# define ARCH_SHSTK_SHSTK 0x1 ++# define ARCH_SHSTK_WRSS 0x2 ++#endif +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c +index 837a9fd0eb..2ea66c803b 100644 +--- a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c ++++ b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c +@@ -87,15 +87,14 @@ do_test (void) + ctx[4].uc_link = &ctx[0]; + makecontext (&ctx[4], (void (*) (void)) f1, 0); + +- /* NB: When shadow stack is enabled, makecontext calls arch_prctl +- with ARCH_CET_ALLOC_SHSTK to allocate a new shadow stack which +- can be unmapped. The base address and size of the new shadow +- stack are returned in __ssp[1] and __ssp[2]. makecontext is +- called for CTX1, CTX3 and CTX4. But only CTX1 is used. New +- shadow stacks are allocated in the order of CTX3, CTX1, CTX4. +- It is very likely that CTX1's shadow stack is placed between +- CTX3 and CTX4. We munmap CTX3's and CTX4's shadow stacks to +- create gaps above and below CTX1's shadow stack. We check ++ /* NB: When shadow stack is enabled, makecontext calls map_shadow_stack ++ to allocate a new shadow stack which can be unmapped. The base ++ address and size of the new shadow stack are returned in __ssp[1] ++ and __ssp[2]. makecontext is called for CTX1, CTX3 and CTX4. But ++ only CTX1 is used. New shadow stacks are allocated in the order ++ of CTX3, CTX1, CTX4. It is very likely that CTX1's shadow stack is ++ placed between CTX3 and CTX4. We munmap CTX3's and CTX4's shadow ++ stacks to create gaps above and below CTX1's shadow stack. We check + that setcontext CTX1 works correctly in this case. */ + if (_get_ssp () != 0) + { +diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile +index 5e19202ebf..06b873949e 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/Makefile ++++ b/sysdeps/unix/sysv/linux/x86_64/Makefile +@@ -3,7 +3,7 @@ sysdep_routines += ioperm iopl + endif + + ifeq ($(subdir),stdlib) +-sysdep_routines += __start_context ++sysdep_routines += __start_context allocate-shadow-stack + endif + + ifeq ($(subdir),csu) +diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sysdeps/unix/sysv/linux/x86_64/__start_context.S +index f6436dd6bb..ae04203c90 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/__start_context.S ++++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S +@@ -24,20 +24,14 @@ + /* Use CALL to push __start_context onto the new stack as well as the new + shadow stack. RDI points to ucontext: + Incoming: +- __ssp[0]: The original caller's shadow stack pointer. +- __ssp[1]: The size of the new shadow stack. +- __ssp[2]: The size of the new shadow stack. +- Outgoing: + __ssp[0]: The new shadow stack pointer. + __ssp[1]: The base address of the new shadow stack. + __ssp[2]: The size of the new shadow stack. + */ + + ENTRY(__push___start_context) +- /* Save the pointer to ucontext. */ +- movq %rdi, %r9 + /* Get the original shadow stack pointer. */ +- rdsspq %r8 ++ rdsspq %rcx + /* Save the original stack pointer. */ + movq %rsp, %rdx + /* Load the top of the new stack into RSI. */ +@@ -45,24 +39,12 @@ ENTRY(__push___start_context) + /* Add 8 bytes to RSI since CALL will push the 8-byte return + address onto stack. */ + leaq 8(%rsi), %rsp +- /* Allocate the new shadow stack. The size of the new shadow +- stack is passed in __ssp[1]. */ +- lea (oSSP + 8)(%rdi), %RSI_LP +- movl $ARCH_CET_ALLOC_SHSTK, %edi +- movl $__NR_arch_prctl, %eax +- /* The new shadow stack base is returned in __ssp[1]. */ +- syscall +- testq %rax, %rax +- jne L(hlt) /* This should never happen. */ +- +- /* Get the size of the new shadow stack. */ +- movq 8(%rsi), %rdi +- +- /* Get the base address of the new shadow stack. */ +- movq (%rsi), %rsi +- ++ /* The size of the new shadow stack is stored in __ssp[2]. */ ++ mov (oSSP + 16)(%rdi), %RSI_LP ++ /* The new shadow stack base is stored in __ssp[1]. */ ++ mov (oSSP + 8)(%rdi), %RAX_LP + /* Use the restore stoken to restore the new shadow stack. */ +- rstorssp -8(%rsi, %rdi) ++ rstorssp -8(%rax, %rsi) + + /* Save the restore token on the original shadow stack. */ + saveprevssp +@@ -73,18 +55,12 @@ ENTRY(__push___start_context) + jmp __start_context + 1: + +- /* Get the new shadow stack pointer. */ +- rdsspq %rdi +- + /* Use the restore stoken to restore the original shadow stack. */ +- rstorssp -8(%r8) ++ rstorssp -8(%rcx) + + /* Save the restore token on the new shadow stack. */ + saveprevssp + +- /* Store the new shadow stack pointer in __ssp[0]. */ +- movq %rdi, oSSP(%r9) +- + /* Restore the original stack. */ + mov %rdx, %rsp + ret +diff --git a/sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.c b/sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.c +new file mode 100644 +index 0000000000..f2e1d03b96 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.c +@@ -0,0 +1,55 @@ ++/* Helper function to allocate shadow stack. ++ Copyright (C) 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 ++ ++/* NB: This can be treated as a syscall by caller. */ ++ ++long int ++__allocate_shadow_stack (size_t stack_size, ++ shadow_stack_size_t *child_stack) ++{ ++#ifdef __NR_map_shadow_stack ++ size_t shadow_stack_size ++ = stack_size >> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT; ++ /* Align shadow stack to 8 bytes. */ ++ shadow_stack_size = ALIGN_UP (shadow_stack_size, 8); ++ /* Since sigaltstack shares shadow stack with the current context in ++ the thread, add extra 20 stack frames in shadow stack for signal ++ handlers. */ ++ shadow_stack_size += 20 * 8; ++ void *shadow_stack = (void *)INLINE_SYSCALL_CALL ++ (map_shadow_stack, NULL, shadow_stack_size, SHADOW_STACK_SET_TOKEN); ++ /* Report the map_shadow_stack error. */ ++ if (shadow_stack == MAP_FAILED) ++ return -errno; ++ ++ /* Save the shadow stack base and size on child stack. */ ++ child_stack[0] = (uintptr_t) shadow_stack; ++ child_stack[1] = shadow_stack_size; ++ ++ return 0; ++#else ++ return -ENOSYS; ++#endif ++} +diff --git a/sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.h b/sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.h +new file mode 100644 +index 0000000000..d05aaf16e5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.h +@@ -0,0 +1,24 @@ ++/* Helper function to allocate shadow stack. ++ Copyright (C) 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 ++ ++typedef __typeof (((ucontext_t *) 0)->__ssp[0]) shadow_stack_size_t; ++ ++extern long int __allocate_shadow_stack (size_t, shadow_stack_size_t *) ++ attribute_hidden; +diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S +index a00e2f6290..71f3802dca 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S ++++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S +@@ -58,35 +58,15 @@ ENTRY(__getcontext) + testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET + jz L(no_shstk) + +- /* Save RDI in RDX which won't be clobbered by syscall. */ +- movq %rdi, %rdx +- + xorl %eax, %eax + cmpq %fs:SSP_BASE_OFFSET, %rax + jnz L(shadow_stack_bound_recorded) + +- /* Get the base address and size of the default shadow stack +- which must be the current shadow stack since nothing has +- been recorded yet. */ +- sub $24, %RSP_LP +- mov %RSP_LP, %RSI_LP +- movl $ARCH_CET_STATUS, %edi +- movl $__NR_arch_prctl, %eax +- syscall +- testq %rax, %rax +- jz L(continue_no_err) +- +- /* This should never happen. */ +- hlt +- +-L(continue_no_err): +- /* Record the base of the current shadow stack. */ +- movq 8(%rsp), %rax ++ /* When the shadow stack base is unset, the default shadow ++ stack is in use. Use the current shadow stack pointer ++ as the marker for the default shadow stack. */ ++ rdsspq %rax + movq %rax, %fs:SSP_BASE_OFFSET +- add $24, %RSP_LP +- +- /* Restore RDI. */ +- movq %rdx, %rdi + + L(shadow_stack_bound_recorded): + /* Get the current shadow stack pointer. */ +@@ -94,7 +74,7 @@ L(shadow_stack_bound_recorded): + /* NB: Save the caller's shadow stack so that we can jump back + to the caller directly. */ + addq $8, %rax +- movq %rax, oSSP(%rdx) ++ movq %rax, oSSP(%rdi) + + /* Save the current shadow stack base in ucontext. */ + movq %fs:SSP_BASE_OFFSET, %rax +diff --git a/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/sysdeps/unix/sysv/linux/x86_64/makecontext.c +index de9e03eb81..e4f025bd50 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c ++++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c +@@ -24,6 +24,7 @@ + # include + # include + # include ++# include + #endif + + #include "ucontext_i.h" +@@ -88,23 +89,24 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) + if ((feature_1 & X86_FEATURE_1_SHSTK) != 0) + { + /* Shadow stack is enabled. We need to allocate a new shadow +- stack. */ +- unsigned long ssp_size = (((uintptr_t) sp +- - (uintptr_t) ucp->uc_stack.ss_sp) +- >> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT); +- /* Align shadow stack to 8 bytes. */ +- ssp_size = ALIGN_UP (ssp_size, 8); +- +- ucp->__ssp[1] = ssp_size; +- ucp->__ssp[2] = ssp_size; +- +- /* Call __push___start_context to allocate a new shadow stack, +- push __start_context onto the new stack as well as the new +- shadow stack. NB: After __push___start_context returns, ++ stack. NB: + ucp->__ssp[0]: The new shadow stack pointer. + ucp->__ssp[1]: The base address of the new shadow stack. + ucp->__ssp[2]: The size of the new shadow stack. + */ ++ long int ret ++ = __allocate_shadow_stack (((uintptr_t) sp ++ - (uintptr_t) ucp->uc_stack.ss_sp), ++ &ucp->__ssp[1]); ++ if (ret != 0) ++ { ++ /* FIXME: What should we do? */ ++ abort (); ++ } ++ ++ ucp->__ssp[0] = ucp->__ssp[1] + ucp->__ssp[2] - 8; ++ /* Call __push___start_context to push __start_context onto the new ++ stack as well as the new shadow stack. */ + __push___start_context (ucp); + } + else +diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S +index 5925752164..2f2fe9875b 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S ++++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S +@@ -109,25 +109,11 @@ ENTRY(__swapcontext) + cmpq %fs:SSP_BASE_OFFSET, %rax + jnz L(shadow_stack_bound_recorded) + +- /* Get the base address and size of the default shadow stack +- which must be the current shadow stack since nothing has +- been recorded yet. */ +- sub $24, %RSP_LP +- mov %RSP_LP, %RSI_LP +- movl $ARCH_CET_STATUS, %edi +- movl $__NR_arch_prctl, %eax +- syscall +- testq %rax, %rax +- jz L(continue_no_err) +- +- /* This should never happen. */ +- hlt +- +-L(continue_no_err): +- /* Record the base of the current shadow stack. */ +- movq 8(%rsp), %rax ++ /* When the shadow stack base is unset, the default shadow ++ stack is in use. Use the current shadow stack pointer ++ as the marker for the default shadow stack. */ ++ rdsspq %rax + movq %rax, %fs:SSP_BASE_OFFSET +- add $24, %RSP_LP + + L(shadow_stack_bound_recorded): + /* If we unwind the stack, we can't undo stack unwinding. Just +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index badf088874..61d3ca38f8 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -1096,8 +1096,9 @@ no_cpuid: + + # ifndef SHARED + /* Check if IBT and SHSTK are enabled by kernel. */ +- if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT) +- || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) ++ if ((cet_status ++ & (GNU_PROPERTY_X86_FEATURE_1_IBT ++ | GNU_PROPERTY_X86_FEATURE_1_SHSTK))) + { + /* Disable IBT and/or SHSTK if they are enabled by kernel, but + disabled by environment variable: +@@ -1106,9 +1107,11 @@ no_cpuid: + */ + unsigned int cet_feature = 0; + if (!CPU_FEATURE_USABLE (IBT)) +- cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT; ++ cet_feature |= (cet_status ++ & GNU_PROPERTY_X86_FEATURE_1_IBT); + if (!CPU_FEATURE_USABLE (SHSTK)) +- cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; ++ cet_feature |= (cet_status ++ & GNU_PROPERTY_X86_FEATURE_1_SHSTK); + + if (cet_feature) + { +@@ -1123,7 +1126,9 @@ no_cpuid: + lock CET if IBT or SHSTK is enabled permissively. */ + if (GL(dl_x86_feature_control).ibt != cet_permissive + && GL(dl_x86_feature_control).shstk != cet_permissive) +- dl_cet_lock_cet (); ++ dl_cet_lock_cet (GL(dl_x86_feature_1) ++ & (GNU_PROPERTY_X86_FEATURE_1_IBT ++ | GNU_PROPERTY_X86_FEATURE_1_SHSTK)); + } + # endif + } +diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c +index e486e549be..66a78244d4 100644 +--- a/sysdeps/x86/dl-cet.c ++++ b/sysdeps/x86/dl-cet.c +@@ -202,7 +202,7 @@ dl_cet_check_startup (struct link_map *m, struct dl_cet_info *info) + feature_1_lock |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + + if (feature_1_lock != 0 +- && dl_cet_lock_cet () != 0) ++ && dl_cet_lock_cet (feature_1_lock) != 0) + _dl_fatal_printf ("%s: can't lock CET\n", info->program); + } + +diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h +index 1403f939f7..4bcc2552a1 100644 +--- a/sysdeps/x86_64/nptl/tls.h ++++ b/sysdeps/x86_64/nptl/tls.h +@@ -60,7 +60,7 @@ typedef struct + void *__private_tm[4]; + /* GCC split stack support. */ + void *__private_ss; +- /* The lowest address of shadow stack, */ ++ /* The marker for the current shadow stack. */ + unsigned long long int ssp_base; + /* Must be kept even if it is no longer used by glibc since programs, + like AddressSanitizer, depend on the size of tcbhead_t. */ +-- +2.27.0 + diff --git a/x86-cet-Update-tst-cet-vfork-1.patch b/x86-cet-Update-tst-cet-vfork-1.patch new file mode 100644 index 0000000..c124f76 --- /dev/null +++ b/x86-cet-Update-tst-cet-vfork-1.patch @@ -0,0 +1,105 @@ +From 4c69161b6343bd47d9c20b8fbdc9cb83627a0bae Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sun, 16 Jan 2022 12:09:57 -0800 +Subject: [PATCH] x86/cet: Update tst-cet-vfork-1 + +Change tst-cet-vfork-1.c to verify that vfork child return triggers +SIGSEGV due to shadow stack mismatch. + +(cherry picked from commit 1a23b39f9d2caeca72dc12adbbcb5d2d632d942a) +--- + sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c | 43 ++++++++----------- + 1 file changed, 17 insertions(+), 26 deletions(-) + +diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c b/sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c +index 9c4b6f4d42..c92ed9e737 100644 +--- a/sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c ++++ b/sysdeps/unix/sysv/linux/x86/tst-cet-vfork-1.c +@@ -18,34 +18,26 @@ + . */ + + #include +-#include + #include + #include + #include + #include + #include + #include +-#include +-#include + + __attribute__ ((noclone, noinline)) + static void + do_test_1 (void) + { + pid_t p1; +- int fd[2]; + +- if (pipe (fd) == -1) +- { +- puts ("pipe failed"); +- _exit (EXIT_FAILURE); +- } ++ /* NB: Since child return pops shadow stack which is shared with ++ parent, child must not return after vfork. */ + + if ((p1 = vfork ()) == 0) + { +- pid_t p = getpid (); +- TEMP_FAILURE_RETRY (write (fd[1], &p, sizeof (p))); +- /* Child return should trigger SIGSEGV. */ ++ /* Child return should trigger SIGSEGV due to shadow stack ++ mismatch. */ + return; + } + else if (p1 == -1) +@@ -54,22 +46,22 @@ do_test_1 (void) + _exit (EXIT_FAILURE); + } + +- pid_t p2 = 0; +- if (TEMP_FAILURE_RETRY (read (fd[0], &p2, sizeof (pid_t))) +- != sizeof (pid_t)) +- puts ("pipd read failed"); +- else ++ int r; ++ if (TEMP_FAILURE_RETRY (waitpid (p1, &r, 0)) != p1) + { +- int r; +- if (TEMP_FAILURE_RETRY (waitpid (p1, &r, 0)) != p1) +- puts ("waitpid failed"); +- else if (r != 0) +- puts ("pip write in child failed"); ++ puts ("waitpid failed"); ++ _exit (EXIT_FAILURE); ++ } ++ ++ if (!WIFSIGNALED (r) || WTERMSIG (r) != SIGSEGV) ++ { ++ puts ("Child not terminated with SIGSEGV"); ++ _exit (EXIT_FAILURE); + } + + /* Parent exits immediately so that parent returns without triggering +- SIGSEGV when shadow stack isn't in use. */ +- _exit (EXIT_FAILURE); ++ SIGSEGV when shadow stack is in use. */ ++ _exit (EXIT_SUCCESS); + } + + static int +@@ -80,9 +72,8 @@ do_test (void) + return EXIT_UNSUPPORTED; + do_test_1 (); + /* Child exits immediately so that child returns without triggering +- SIGSEGV when shadow stack isn't in use. */ ++ SIGSEGV when shadow stack is in use. */ + _exit (EXIT_FAILURE); + } + +-#define EXPECTED_SIGNAL (_get_ssp () == 0 ? 0 : SIGSEGV) + #include +-- +2.27.0 + diff --git a/x86-cet-fix-shadow-stack-test-scripts.patch b/x86-cet-fix-shadow-stack-test-scripts.patch new file mode 100644 index 0000000..314c16a --- /dev/null +++ b/x86-cet-fix-shadow-stack-test-scripts.patch @@ -0,0 +1,64 @@ +From 89fd3b08eaace2636abfa7e3cc01a2700367cc24 Mon Sep 17 00:00:00 2001 +From: Michael Jeanson +Date: Mon, 5 Feb 2024 15:22:39 -0500 +Subject: [PATCH] x86/cet: fix shadow stack test scripts + +Some shadow stack test scripts use the '==' operator with the 'test' +command to validate exit codes resulting in the following error: + + sysdeps/x86_64/tst-shstk-legacy-1e.sh: 31: test: 139: unexpected operator + +The '==' operator is invalid for the 'test' command, use '-eq' like the +previous call to 'test'. + +Signed-off-by: Michael Jeanson +Reviewed-by: H.J. Lu +(cherry picked from commit 155bb9d036646138348fee0ac045de601811e0c5) +--- + sysdeps/x86_64/tst-shstk-legacy-1e-static.sh | 2 +- + sysdeps/x86_64/tst-shstk-legacy-1e.sh | 2 +- + sysdeps/x86_64/tst-shstk-legacy-1g.sh | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh +index 008c50dae3..b0bb7150b8 100755 +--- a/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh ++++ b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh +@@ -26,7 +26,7 @@ ${common_objpfx}elf/tst-shstk-legacy-1e-static + status=$? + if test $status -eq 77; then + exit 77 +-elif test $status == 139; then ++elif test $status -eq 139; then + exit 0 + else + exit 1 +diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e.sh b/sysdeps/x86_64/tst-shstk-legacy-1e.sh +index 82f2acbf75..4080b277c2 100755 +--- a/sysdeps/x86_64/tst-shstk-legacy-1e.sh ++++ b/sysdeps/x86_64/tst-shstk-legacy-1e.sh +@@ -28,7 +28,7 @@ ${test_program_prefix} \ + status=$? + if test $status -eq 77; then + exit 77 +-elif test $status == 139; then ++elif test $status -eq 139; then + exit 0 + else + exit 1 +diff --git a/sysdeps/x86_64/tst-shstk-legacy-1g.sh b/sysdeps/x86_64/tst-shstk-legacy-1g.sh +index 261eef7cac..878e360ba3 100755 +--- a/sysdeps/x86_64/tst-shstk-legacy-1g.sh ++++ b/sysdeps/x86_64/tst-shstk-legacy-1g.sh +@@ -28,7 +28,7 @@ ${test_program_prefix} \ + status=$? + if test $status -eq 77; then + exit 77 +-elif test $status == 139; then ++elif test $status -eq 139; then + exit 0 + else + exit 1 +-- +2.27.0 + -- Gitee