From a5464690b5de68fe891f162253e8b160787073a5 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Tue, 1 Aug 2023 14:10:29 -0400 Subject: [PATCH] Drop downstream glibc shadow stack userspace support patches The kernel patches are still stuck and there's a risk that the interfaces may change. --- 0001-x86-cet-Don-t-set-CET-active.patch | 71 -- glibc.spec | 22 +- ...cet-Check-user_shstk-in-proc-cpuinfo.patch | 27 - v2-0002-x86-cet-Update-tst-cet-vfork-1.patch | 103 --- ...-Don-t-assume-that-SHSTK-implies-IBT.patch | 98 --- ...eck-legacy-shadow-stack-applications.patch | 209 ----- ...-CPU_FEATURE_ACTIVE-when-CET-is-disa.patch | 61 -- ...ests-for-GLIBC_TUNABLES-glibc.cpu.hw.patch | 81 -- ...-legacy-shadow-stack-code-in-.init_a.patch | 456 ---------- ...-CPU_FEATURE_ACTIVE-in-permissive-mo.patch | 49 -- v2-0009-x86-Check-PT_GNU_PROPERTY-early.patch | 160 ---- ...-x86-Modularize-sysdeps-x86-dl-cet.c.patch | 511 ----------- ...xup-asm-unistd.h-and-regenerate-arch.patch | 96 --- ...with-the-kernel-shadow-stack-interfa.patch | 803 ------------------ ...rovide-_dl_get_dl_main_map-in-libc.a.patch | 59 -- ...t-Enable-shadow-stack-during-startup.patch | 518 ----------- ...-feature_1-in-TCB-for-active-IBT-and.patch | 89 -- 17 files changed, 4 insertions(+), 3409 deletions(-) delete mode 100644 0001-x86-cet-Don-t-set-CET-active.patch delete mode 100644 v2-0001-x86-cet-Check-user_shstk-in-proc-cpuinfo.patch delete mode 100644 v2-0002-x86-cet-Update-tst-cet-vfork-1.patch delete mode 100644 v2-0003-x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch delete mode 100644 v2-0004-x86-cet-Check-legacy-shadow-stack-applications.patch delete mode 100644 v2-0005-x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disa.patch delete mode 100644 v2-0006-x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hw.patch delete mode 100644 v2-0007-x86-cet-Check-legacy-shadow-stack-code-in-.init_a.patch delete mode 100644 v2-0008-x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mo.patch delete mode 100644 v2-0009-x86-Check-PT_GNU_PROPERTY-early.patch delete mode 100644 v2-0010-x86-Modularize-sysdeps-x86-dl-cet.c.patch delete mode 100644 v2-0011-x86-64-Add-fixup-asm-unistd.h-and-regenerate-arch.patch delete mode 100644 v2-0012-x86-cet-Sync-with-the-kernel-shadow-stack-interfa.patch delete mode 100644 v2-0013-elf-Always-provide-_dl_get_dl_main_map-in-libc.a.patch delete mode 100644 v2-0014-x86-cet-Enable-shadow-stack-during-startup.patch delete mode 100644 v2-0015-x86-cet-Check-feature_1-in-TCB-for-active-IBT-and.patch diff --git a/0001-x86-cet-Don-t-set-CET-active.patch b/0001-x86-cet-Don-t-set-CET-active.patch deleted file mode 100644 index d2bdfb4..0000000 --- a/0001-x86-cet-Don-t-set-CET-active.patch +++ /dev/null @@ -1,71 +0,0 @@ -From c35bffd52dceed849fa027d607c0671049ee1428 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 12 May 2023 13:52:16 -0700 -Subject: [PATCH] x86/cet: Don't set CET active - -Don't set CET active so that CET is disabled by default. Shadow stack -can be enabled by - -$ export GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK - -if shadow stack can be enabled by kernel. ---- - sysdeps/x86/cpu-features.c | 2 +- - sysdeps/x86/cpu-tunables.c | 17 ++++++++++++++++- - 2 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index 45bc7fcac3..490a7e38be 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..eb5d31821b 100644 ---- a/sysdeps/x86/cpu-tunables.c -+++ b/sysdeps/x86/cpu-tunables.c -@@ -47,6 +47,18 @@ 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 +174,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.40.1 - diff --git a/glibc.spec b/glibc.spec index b7382fa..dec5270 100644 --- a/glibc.spec +++ b/glibc.spec @@ -159,7 +159,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 1 +%global baserelease 2 Release: %{baserelease}%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for @@ -232,23 +232,6 @@ Patch17: glibc-cs-path.patch Patch23: glibc-python3.patch Patch24: glibc-disable-werror-tst-realloc.patch -Patch100: v2-0001-x86-cet-Check-user_shstk-in-proc-cpuinfo.patch -Patch101: v2-0002-x86-cet-Update-tst-cet-vfork-1.patch -Patch102: v2-0003-x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch -Patch103: v2-0004-x86-cet-Check-legacy-shadow-stack-applications.patch -Patch104: v2-0005-x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disa.patch -Patch105: v2-0006-x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hw.patch -Patch106: v2-0007-x86-cet-Check-legacy-shadow-stack-code-in-.init_a.patch -Patch107: v2-0008-x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mo.patch -Patch108: v2-0009-x86-Check-PT_GNU_PROPERTY-early.patch -Patch109: v2-0010-x86-Modularize-sysdeps-x86-dl-cet.c.patch -Patch110: v2-0011-x86-64-Add-fixup-asm-unistd.h-and-regenerate-arch.patch -Patch111: v2-0012-x86-cet-Sync-with-the-kernel-shadow-stack-interfa.patch -Patch112: v2-0013-elf-Always-provide-_dl_get_dl_main_map-in-libc.a.patch -Patch113: v2-0014-x86-cet-Enable-shadow-stack-during-startup.patch -Patch114: v2-0015-x86-cet-Check-feature_1-in-TCB-for-active-IBT-and.patch -Patch115: 0001-x86-cet-Don-t-set-CET-active.patch - ############################################################################## # Continued list of core "glibc" package information: ############################################################################## @@ -2213,6 +2196,9 @@ update_gconv_modules_cache () %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Tue Aug 1 2023 Siddhesh Poyarekar - 2.38-2 +- Drop downstream glibc shadow stack userspace support patches. + * Tue Aug 1 2023 Florian Weimer - 2.38-1 - Switch to upstream 2.38 release - : Add APX support diff --git a/v2-0001-x86-cet-Check-user_shstk-in-proc-cpuinfo.patch b/v2-0001-x86-cet-Check-user_shstk-in-proc-cpuinfo.patch deleted file mode 100644 index 25aba86..0000000 --- a/v2-0001-x86-cet-Check-user_shstk-in-proc-cpuinfo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From c94d3234c48c9e8196144bfc150a8f7eee770986 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Wed, 1 Mar 2023 11:26:03 -0800 -Subject: [PATCH v2 01/15] x86/cet: Check user_shstk in /proc/cpuinfo - -Linux kernel reports CPU shadow stack feature in /proc/cpuinfo as -user_shstk, instead of shstk. ---- - 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.40.1 - diff --git a/v2-0002-x86-cet-Update-tst-cet-vfork-1.patch b/v2-0002-x86-cet-Update-tst-cet-vfork-1.patch deleted file mode 100644 index d2ce592..0000000 --- a/v2-0002-x86-cet-Update-tst-cet-vfork-1.patch +++ /dev/null @@ -1,103 +0,0 @@ -From f722c6853035ab390757eb725e0661cf22b9791e Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Sun, 16 Jan 2022 12:09:57 -0800 -Subject: [PATCH v2 02/15] 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. ---- - 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.40.1 - diff --git a/v2-0003-x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch b/v2-0003-x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch deleted file mode 100644 index 67b8c31..0000000 --- a/v2-0003-x86-cet-Don-t-assume-that-SHSTK-implies-IBT.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 361cb3ec2ab4322f860d18a3a1d674603fe275c5 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Sun, 16 Jan 2022 18:23:58 -0800 -Subject: [PATCH v2 03/15] 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. ---- - 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 917c26f116..ea45aad34c 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -165,7 +165,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.40.1 - diff --git a/v2-0004-x86-cet-Check-legacy-shadow-stack-applications.patch b/v2-0004-x86-cet-Check-legacy-shadow-stack-applications.patch deleted file mode 100644 index 77e90c5..0000000 --- a/v2-0004-x86-cet-Check-legacy-shadow-stack-applications.patch +++ /dev/null @@ -1,209 +0,0 @@ -From 2db487201909cf8fc1216e0b41e5bdd0d6677460 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Tue, 21 Mar 2023 12:53:24 -0700 -Subject: [PATCH v2 04/15] 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. ---- - 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 ea45aad34c..dea14e343c 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -129,6 +129,21 @@ tests += tst-cet-legacy-1 tst-cet-legacy-1a tst-cet-legacy-2 \ - tst-cet-legacy-10 tst-cet-legacy-10-static - tests-static += tst-cet-legacy-9-static tst-cet-legacy-10-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 tst-cet-legacy-4c \ - tst-cet-legacy-5b tst-cet-legacy-6b - modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \ -@@ -168,6 +183,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 \ -@@ -200,6 +218,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.40.1 - diff --git a/v2-0005-x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disa.patch b/v2-0005-x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disa.patch deleted file mode 100644 index 1ae6e2c..0000000 --- a/v2-0005-x86-cet-Check-CPU_FEATURE_ACTIVE-when-CET-is-disa.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 13543173f98ca8f01311fa6a2bca409128561d18 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 10 Mar 2023 13:18:10 -0800 -Subject: [PATCH v2 05/15] x86/cet: Check CPU_FEATURE_ACTIVE when CET is - disabled - -Verify that CPU_FEATURE_ACTIVE (SHSTK) works properly when CET is -disabled. ---- - sysdeps/x86/Makefile | 8 ++++++-- - sysdeps/x86/tst-cet-legacy-10a-static.c | 2 ++ - sysdeps/x86/tst-cet-legacy-10a.c | 2 ++ - 3 files changed, 10 insertions(+), 2 deletions(-) - 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 dea14e343c..580c3ecdc5 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -126,8 +126,10 @@ 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 --tests-static += tst-cet-legacy-9-static tst-cet-legacy-10-static -+ tst-cet-legacy-10 tst-cet-legacy-10-static \ -+ tst-cet-legacy-10a tst-cet-legacy-10a-static -+tests-static += tst-cet-legacy-9-static tst-cet-legacy-10-static \ -+ tst-cet-legacy-10a-static - tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd) - - tests += \ -@@ -182,6 +184,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.40.1 - diff --git a/v2-0006-x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hw.patch b/v2-0006-x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hw.patch deleted file mode 100644 index 76f5e00..0000000 --- a/v2-0006-x86-cet-Add-tests-for-GLIBC_TUNABLES-glibc.cpu.hw.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 7a97a9ab63a37ae1191e514258e4f6fefdc2e41b Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 17 Mar 2023 16:21:49 -0700 -Subject: [PATCH v2 06/15] x86/cet: Add tests for - GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK - -Verify that GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK turns off shadow -stack properly. ---- - 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 580c3ecdc5..5f1414fba3 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -137,10 +137,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 \ -@@ -227,6 +230,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.40.1 - diff --git a/v2-0007-x86-cet-Check-legacy-shadow-stack-code-in-.init_a.patch b/v2-0007-x86-cet-Check-legacy-shadow-stack-code-in-.init_a.patch deleted file mode 100644 index fb73597..0000000 --- a/v2-0007-x86-cet-Check-legacy-shadow-stack-code-in-.init_a.patch +++ /dev/null @@ -1,456 +0,0 @@ -From d3bf3cba97111334082b817e59ff2840dbc98afa Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Wed, 22 Mar 2023 13:34:55 -0700 -Subject: [PATCH v2 07/15] 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. ---- - 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 5f1414fba3..b8b98177e0 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -139,11 +139,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 \ -@@ -192,6 +203,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 -@@ -234,6 +248,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.40.1 - diff --git a/v2-0008-x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mo.patch b/v2-0008-x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mo.patch deleted file mode 100644 index 1c26421..0000000 --- a/v2-0008-x86-cet-Check-CPU_FEATURE_ACTIVE-in-permissive-mo.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 8230fefd2495d1fb7fa72c680dc10ae4d10fde61 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Tue, 28 Mar 2023 13:52:36 -0700 -Subject: [PATCH v2 08/15] x86/cet: Check CPU_FEATURE_ACTIVE in permissive mode - -Verify that CPU_FEATURE_ACTIVE works properly in permissive mode. ---- - 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 b8b98177e0..6ceefe16c7 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -174,6 +174,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.40.1 - diff --git a/v2-0009-x86-Check-PT_GNU_PROPERTY-early.patch b/v2-0009-x86-Check-PT_GNU_PROPERTY-early.patch deleted file mode 100644 index 01ec3c0..0000000 --- a/v2-0009-x86-Check-PT_GNU_PROPERTY-early.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 4323e979bd1745e10ae29667c290bff7f74d38e4 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Thu, 13 Jan 2022 14:45:46 -0800 -Subject: [PATCH v2 09/15] x86: Check PT_GNU_PROPERTY early - -The PT_GNU_PROPERTY segment is scanned before PT_NOTE. For binaries -with the PT_GNU_PROPERTY segment, we can check it to avoid scan of -the PT_NOTE segment. ---- - sysdeps/x86/dl-prop.h | 120 ++++++++++++++++++++++++++++-------------- - 1 file changed, 80 insertions(+), 40 deletions(-) - -diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h -index 87702df040..ca07b83701 100644 ---- a/sysdeps/x86/dl-prop.h -+++ b/sysdeps/x86/dl-prop.h -@@ -81,6 +81,60 @@ _dl_open_check (struct link_map *m) - #endif - } - -+/* Check the GNU property and return its value. It returns: -+ -1: Skip this note. -+ 0: Stop checking. -+ 1: Continue to check. -+ */ -+static inline int -+_dl_check_gnu_property (unsigned int type, unsigned int datasz, -+ void *ptr, unsigned int *feature_1_and, -+ unsigned int *needed_1, -+ unsigned int *isa_1_needed) -+{ -+ if (type == GNU_PROPERTY_X86_FEATURE_1_AND -+ || type == GNU_PROPERTY_X86_ISA_1_NEEDED -+ || type == GNU_PROPERTY_1_NEEDED) -+ { -+ /* The sizes of types which we are searching for are -+ 4 bytes. There is no point to continue if this -+ note is ill-formed. */ -+ if (datasz != 4) -+ return -1; -+ -+ /* NB: Stop the scan only after seeing all types which -+ we are searching for. */ -+ _Static_assert (((GNU_PROPERTY_X86_ISA_1_NEEDED -+ > GNU_PROPERTY_X86_FEATURE_1_AND) -+ && (GNU_PROPERTY_X86_FEATURE_1_AND -+ > GNU_PROPERTY_1_NEEDED)), -+ "GNU_PROPERTY_X86_ISA_1_NEEDED > " -+ "GNU_PROPERTY_X86_FEATURE_1_AND && " -+ "GNU_PROPERTY_X86_FEATURE_1_AND > " -+ "GNU_PROPERTY_1_NEEDED"); -+ if (type == GNU_PROPERTY_X86_FEATURE_1_AND) -+ *feature_1_and = *(unsigned int *) ptr; -+ else if (type == GNU_PROPERTY_1_NEEDED) -+ *needed_1 = *(unsigned int *) ptr; -+ else -+ { -+ *isa_1_needed = *(unsigned int *) ptr; -+ -+ /* Keep searching for the next GNU property note -+ generated by the older linker. */ -+ return 0; -+ } -+ } -+ else if (type > GNU_PROPERTY_X86_ISA_1_NEEDED) -+ { -+ /* Stop the scan since property type is in ascending -+ order. */ -+ return 0; -+ } -+ -+ return 1; -+} -+ - static inline void __attribute__ ((unused)) - _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note, - const ElfW(Addr) size, const ElfW(Addr) align) -@@ -141,45 +195,14 @@ _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note, - - last_type = type; - -- if (type == GNU_PROPERTY_X86_FEATURE_1_AND -- || type == GNU_PROPERTY_X86_ISA_1_NEEDED -- || type == GNU_PROPERTY_1_NEEDED) -- { -- /* The sizes of types which we are searching for are -- 4 bytes. There is no point to continue if this -- note is ill-formed. */ -- if (datasz != 4) -- return; -- -- /* NB: Stop the scan only after seeing all types which -- we are searching for. */ -- _Static_assert (((GNU_PROPERTY_X86_ISA_1_NEEDED -- > GNU_PROPERTY_X86_FEATURE_1_AND) -- && (GNU_PROPERTY_X86_FEATURE_1_AND -- > GNU_PROPERTY_1_NEEDED)), -- "GNU_PROPERTY_X86_ISA_1_NEEDED > " -- "GNU_PROPERTY_X86_FEATURE_1_AND && " -- "GNU_PROPERTY_X86_FEATURE_1_AND > " -- "GNU_PROPERTY_1_NEEDED"); -- if (type == GNU_PROPERTY_X86_FEATURE_1_AND) -- feature_1_and = *(unsigned int *) ptr; -- else if (type == GNU_PROPERTY_1_NEEDED) -- needed_1 = *(unsigned int *) ptr; -- else -- { -- isa_1_needed = *(unsigned int *) ptr; -- -- /* Keep searching for the next GNU property note -- generated by the older linker. */ -- break; -- } -- } -- else if (type > GNU_PROPERTY_X86_ISA_1_NEEDED) -- { -- /* Stop the scan since property type is in ascending -- order. */ -- break; -- } -+ int result = _dl_check_gnu_property (type, datasz, ptr, -+ &feature_1_and, -+ &needed_1, -+ &isa_1_needed); -+ if (result == -1) -+ return; /* Skip this note. */ -+ else if (result == 0) -+ break; /* Stop checking. */ - - /* Check the next property item. */ - ptr += ALIGN_UP (datasz, sizeof (ElfW(Addr))); -@@ -217,7 +240,24 @@ static inline int __attribute__ ((always_inline)) - _dl_process_gnu_property (struct link_map *l, int fd, uint32_t type, - uint32_t datasz, void *data) - { -- return 0; -+ /* This is called on each GNU property. */ -+ unsigned int needed_1 = 0; -+ unsigned int feature_1_and = 0; -+ unsigned int isa_1_needed = 0; -+ int result = _dl_check_gnu_property (type, datasz, data, -+ &feature_1_and, &needed_1, -+ &isa_1_needed); -+ if (needed_1 != 0) -+ l->l_1_needed = needed_1; -+ if (isa_1_needed != 0) -+ l->l_x86_isa_1_needed = isa_1_needed; -+ if (feature_1_and != 0) -+ l->l_x86_feature_1_and = feature_1_and; -+ if ((needed_1 | isa_1_needed | feature_1_and) != 0) -+ l->l_property = lc_property_valid; -+ else if (l->l_property == lc_property_unknown) -+ l->l_property = lc_property_none; -+ return result <= 0 ? 0 : result; - } - - #endif /* _DL_PROP_H */ --- -2.40.1 - diff --git a/v2-0010-x86-Modularize-sysdeps-x86-dl-cet.c.patch b/v2-0010-x86-Modularize-sysdeps-x86-dl-cet.c.patch deleted file mode 100644 index ca881d2..0000000 --- a/v2-0010-x86-Modularize-sysdeps-x86-dl-cet.c.patch +++ /dev/null @@ -1,511 +0,0 @@ -From 8431e78b2df0ee194ac0bbd5a5136e89765444c4 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 24 Mar 2023 13:20:06 -0700 -Subject: [PATCH v2 10/15] 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. ---- - 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.40.1 - diff --git a/v2-0011-x86-64-Add-fixup-asm-unistd.h-and-regenerate-arch.patch b/v2-0011-x86-64-Add-fixup-asm-unistd.h-and-regenerate-arch.patch deleted file mode 100644 index 1dc95c0..0000000 --- a/v2-0011-x86-64-Add-fixup-asm-unistd.h-and-regenerate-arch.patch +++ /dev/null @@ -1,96 +0,0 @@ -From da84f75756ca022e84be6fefd2b8167852949612 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 7 Jan 2022 14:31:25 -0800 -Subject: [PATCH v2 11/15] x86-64: Add and regenerate - arch-syscall.h - -Add the map_shadow_stack system call to Linux/x86-64. ---- - sysdeps/unix/sysv/linux/syscall-names.list | 1 + - .../unix/sysv/linux/x86_64/64/arch-syscall.h | 1 + - .../sysv/linux/x86_64/64/fixup-asm-unistd.h | 20 +++++++++++++++++++ - .../unix/sysv/linux/x86_64/x32/arch-syscall.h | 1 + - .../sysv/linux/x86_64/x32/fixup-asm-unistd.h | 4 ++++ - 5 files changed, 27 insertions(+) - create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/fixup-asm-unistd.h - -diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list -index 5d27b5279c..2bb924c8c4 100644 ---- a/sysdeps/unix/sysv/linux/syscall-names.list -+++ b/sysdeps/unix/sysv/linux/syscall-names.list -@@ -245,6 +245,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 b4ab892ec1..c09890ab74 100644 ---- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h -+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h -@@ -152,6 +152,7 @@ - #define __NR_lsetxattr 189 - #define __NR_lstat 6 - #define __NR_madvise 28 -+#define __NR_map_shadow_stack 451 - #define __NR_mbind 237 - #define __NR_membarrier 324 - #define __NR_memfd_create 319 -diff --git a/sysdeps/unix/sysv/linux/x86_64/64/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/x86_64/64/fixup-asm-unistd.h -new file mode 100644 -index 0000000000..20d941796d ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86_64/64/fixup-asm-unistd.h -@@ -0,0 +1,20 @@ -+/* Regularize definitions. X86-64/64 version. -+ 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 -+ . */ -+ -+#ifndef __NR_map_shadow_stack -+# define __NR_map_shadow_stack 451 -+#endif -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 772559c87b..7ad88cb20d 100644 ---- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h -+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h -@@ -146,6 +146,7 @@ - #define __NR_lsetxattr 1073742013 - #define __NR_lstat 1073741830 - #define __NR_madvise 1073741852 -+#define __NR_map_shadow_stack 1073742275 - #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..882a2ad8c8 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 1073742275 -+#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.40.1 - diff --git a/v2-0012-x86-cet-Sync-with-the-kernel-shadow-stack-interfa.patch b/v2-0012-x86-cet-Sync-with-the-kernel-shadow-stack-interfa.patch deleted file mode 100644 index 7b80049..0000000 --- a/v2-0012-x86-cet-Sync-with-the-kernel-shadow-stack-interfa.patch +++ /dev/null @@ -1,803 +0,0 @@ -From fc14bc65a7e0d3fbe5d939272f25d2e81100e44a Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Sat, 15 Aug 2020 08:04:23 -0700 -Subject: [PATCH v2 12/15] x86/cet: Sync with the kernel shadow stack interface - -Sync with the upstream shadow stack kernel. Although shadow stack is -only supported for x86-64, the i386 shadow stack support is also adjusted. -Don't enable CET for i386 since CET won't work on 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. -2. Allocate shadow stack with the map_shadow_stack syscall. -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. ---- - sysdeps/i386/nptl/tls.h | 2 +- - sysdeps/unix/sysv/linux/i386/getcontext.S | 28 +----- - sysdeps/unix/sysv/linux/i386/makecontext.S | 88 +++++++------------ - sysdeps/unix/sysv/linux/i386/swapcontext.S | 22 +---- - sysdeps/unix/sysv/linux/x86/Makefile | 1 + - .../sysv/linux/x86/allocate-shadow-stack.c | 54 ++++++++++++ - .../sysv/linux/x86/allocate-shadow-stack.h | 27 ++++++ - 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 ++-- - .../unix/sysv/linux/x86_64/__start_context.S | 38 ++------ - sysdeps/unix/sysv/linux/x86_64/getcontext.S | 30 ++----- - sysdeps/unix/sysv/linux/x86_64/makecontext.c | 29 +++--- - 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 +- - 19 files changed, 218 insertions(+), 230 deletions(-) - create mode 100644 sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c - create mode 100644 sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h - -diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h -index 95e7c5be51..da4b83dd49 100644 ---- a/sysdeps/i386/nptl/tls.h -+++ b/sysdeps/i386/nptl/tls.h -@@ -49,7 +49,7 @@ typedef struct - void *__private_tm[3]; - /* GCC split stack support. */ - void *__private_ss; -- /* The lowest address of shadow stack, */ -+ /* The marker for the current shadow stack. */ - unsigned long ssp_base; - } tcbhead_t; - -diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S -index b69a73847b..49ece43dd2 100644 ---- a/sysdeps/unix/sysv/linux/i386/getcontext.S -+++ b/sysdeps/unix/sysv/linux/i386/getcontext.S -@@ -54,31 +54,11 @@ ENTRY(__getcontext) - 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 -+ /* 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. */ -+ rdsspd %eax - movl %eax, %gs:SSP_BASE_OFFSET -- add $24, %esp - - L(shadow_stack_bound_recorded): - /* Load address of the context data structure. */ -diff --git a/sysdeps/unix/sysv/linux/i386/makecontext.S b/sysdeps/unix/sysv/linux/i386/makecontext.S -index 346cdd0e0a..bf481420dc 100644 ---- a/sysdeps/unix/sysv/linux/i386/makecontext.S -+++ b/sysdeps/unix/sysv/linux/i386/makecontext.S -@@ -73,28 +73,37 @@ ENTRY(__makecontext) - 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. Load the pointer to ucontext in -+ ECX. */ -+ movl 4(%esp), %ecx -+ -+ /* Pass the address of __ssp[1] in EDX. */ -+ leal (oSSP + 4)(%ecx), %edx -+ /* Pass stack size in EAX. */ -+ movl oSS_SIZE(%ecx), %eax -+ -+ /* Call __allocate_shadow_stack to allocate a new shadow stack. */ -+ call __allocate_shadow_stack -+ /* Check for error return. */ -+ testl %eax, %eax -+ jne L(hlt) /* This should never happen. */ - -- /* 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 -+ /* Reload the pointer to ucontext into ECX. */ -+ movl 4(%esp), %ecx - -- /* Align shadow stack size to 8 bytes. */ -- addl $7, %edx -- andl $-8, %edx -+ /* Load the base address of the new shadow stack into EAX. */ -+ movl (oSSP + 4)(%ecx), %eax - -- /* Store shadow stack size in __ssp[2]. */ -- movl %edx, (oSSP + 8)(%eax) -+ /* Store the new shadow stack pointer, the shadow stack base + -+ the shadow stack size - 4, in __ssp[0]. */ -+ addl (oSSP + 8)(%ecx), %eax -+ subl $4, %eax -+ movl %eax, oSSP(%ecx) - - /* Save ESI in the second scratch register slot. */ -- movl %esi, oSCRATCH2(%eax) -+ movl %esi, oSCRATCH2(%ecx) - /* Save EDI in the third scratch register slot. */ -- movl %edi, oSCRATCH3(%eax) -- -- /* Save the pointer to ucontext. */ -- movl %eax, %edi -+ movl %edi, oSCRATCH3(%ecx) - - /* Get the original shadow stack pointer. */ - rdsspd %esi -@@ -104,7 +113,7 @@ ENTRY(__makecontext) - andl $-8, %esi - - /* Load the top of the new stack into EDX. */ -- movl oESP(%eax), %edx -+ movl oESP(%ecx), %edx - - /* We need to terminate the FDE here because the unwinder looks - at ra-1 for unwind information. */ -@@ -118,39 +127,14 @@ ENTRY(__makecontext) - 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 -+ /* Load the new shadow stack base in __ssp[1] into EAX. */ -+ movl (oSSP + 4)(%ecx), %eax - -- /* 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 -+ /* Load the new shadow stack size in __ssp[2] into EDI. */ -+ movl (oSSP + 8)(%ecx), %edi - - /* Use the restore stoken to restore the new shadow stack. */ -- rstorssp -8(%eax, %ecx) -+ rstorssp -8(%eax, %edi) - - /* Save the restore token at the next 8 byte aligned boundary - on the original shadow stack. */ -@@ -162,27 +146,21 @@ ENTRY(__makecontext) - 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 -+ movl oSCRATCH2(%ecx), %esi - /* Restore EDI from the third scratch register slot. */ -- movl oSCRATCH3(%edi), %edi -+ movl oSCRATCH3(%ecx), %edi - - ret - -diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S -index 551df10c91..d4f31fa5d5 100644 ---- a/sysdeps/unix/sysv/linux/i386/swapcontext.S -+++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S -@@ -85,25 +85,11 @@ ENTRY(__swapcontext) - 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 -+ /* 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. */ -+ rdsspd %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. */ -diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile -index 9dfdd689a9..ed0d6500b9 100644 ---- a/sysdeps/unix/sysv/linux/x86/Makefile -+++ b/sysdeps/unix/sysv/linux/x86/Makefile -@@ -44,6 +44,7 @@ CFLAGS-tst-cet-vfork-1.c += -mshstk - endif - - ifeq ($(subdir),stdlib) -+sysdep_routines += allocate-shadow-stack - tests += tst-cet-setcontext-1 - CFLAGS-tst-cet-setcontext-1.c += -mshstk - endif -diff --git a/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c -new file mode 100644 -index 0000000000..3a76db1a60 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c -@@ -0,0 +1,54 @@ -+/* 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. */ -+ -+#ifndef __x86_64__ -+__attribute__ ((regparm (2))) -+#endif -+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); -+ 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/allocate-shadow-stack.h b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h -new file mode 100644 -index 0000000000..834373e0d3 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h -@@ -0,0 +1,27 @@ -+/* 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 *) -+#ifndef __x86_64__ -+ __attribute__ ((regparm (2))) -+#endif -+ attribute_hidden; -diff --git a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix/sysv/linux/x86/bits/mman.h -index b335ceff43..17bb078375 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 allocatd 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/__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/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..788b730132 100644 ---- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c -+++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c -@@ -24,6 +24,8 @@ - # include - # include - # include -+# include -+# include - #endif - - #include "ucontext_i.h" -@@ -88,23 +90,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 5bff8ec0b4..6c0d6c100d 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -851,8 +851,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: -@@ -861,9 +862,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) - { -@@ -878,7 +881,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 67c51ee8c2..8b911fd931 100644 ---- a/sysdeps/x86/dl-cet.c -+++ b/sysdeps/x86/dl-cet.c -@@ -201,7 +201,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.40.1 - diff --git a/v2-0013-elf-Always-provide-_dl_get_dl_main_map-in-libc.a.patch b/v2-0013-elf-Always-provide-_dl_get_dl_main_map-in-libc.a.patch deleted file mode 100644 index a39200d..0000000 --- a/v2-0013-elf-Always-provide-_dl_get_dl_main_map-in-libc.a.patch +++ /dev/null @@ -1,59 +0,0 @@ -From dfb1d9949aca739933464bde8710375358536047 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 14 Jan 2022 06:04:25 -0800 -Subject: [PATCH v2 13/15] elf: Always provide _dl_get_dl_main_map in libc.a - -Always provide _dl_get_dl_main_map in libc.a. It will be used by x86 -to process PT_GNU_PROPERTY segment. ---- - elf/dl-support.c | 2 -- - sysdeps/generic/ldsodefs.h | 8 ++++---- - 2 files changed, 4 insertions(+), 6 deletions(-) - -diff --git a/elf/dl-support.c b/elf/dl-support.c -index 322599916f..042be8a433 100644 ---- a/elf/dl-support.c -+++ b/elf/dl-support.c -@@ -353,7 +353,6 @@ _dl_non_dynamic_init (void) - DL_SYSINFO_IMPLEMENTATION - #endif - --#if ENABLE_STATIC_PIE - /* Since relocation to hidden _dl_main_map causes relocation overflow on - aarch64, a function is used to get the address of _dl_main_map. */ - -@@ -362,7 +361,6 @@ _dl_get_dl_main_map (void) - { - return &_dl_main_map; - } --#endif - - /* This is used by _dl_runtime_profile, not used on static code. */ - void -diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h -index ba53176296..7a0903cb8a 100644 ---- a/sysdeps/generic/ldsodefs.h -+++ b/sysdeps/generic/ldsodefs.h -@@ -1172,15 +1172,15 @@ void __libc_setup_tls (void); - # if ENABLE_STATIC_PIE - /* Relocate static executable with PIE. */ - extern void _dl_relocate_static_pie (void) attribute_hidden; -- --/* Get a pointer to _dl_main_map. */ --extern struct link_map * _dl_get_dl_main_map (void) -- __attribute__ ((visibility ("hidden"))); - # else - # define _dl_relocate_static_pie() - # endif - #endif - -+/* Get a pointer to _dl_main_map. */ -+extern struct link_map * _dl_get_dl_main_map (void) -+ __attribute__ ((visibility ("hidden"))); -+ - /* Perform early memory allocation, avoiding a TCB dependency. - Terminate the process if allocation fails. May attempt to use - brk. */ --- -2.40.1 - diff --git a/v2-0014-x86-cet-Enable-shadow-stack-during-startup.patch b/v2-0014-x86-cet-Enable-shadow-stack-during-startup.patch deleted file mode 100644 index 535f499..0000000 --- a/v2-0014-x86-cet-Enable-shadow-stack-during-startup.patch +++ /dev/null @@ -1,518 +0,0 @@ -From 29b8bde6bbe322ea35f494b4f3dae3d5d55d3949 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Thu, 13 Jan 2022 15:35:07 -0800 -Subject: [PATCH v2 14/15] 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. ---- - sysdeps/unix/sysv/linux/x86/cpu-features.c | 49 -------------- - sysdeps/unix/sysv/linux/x86/dl-cet.h | 23 +++++++ - 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 | 77 +++++++++++----------- - sysdeps/x86/get-cpuid-feature-leaf.c | 2 +- - sysdeps/x86/include/cpu-features.h | 3 + - sysdeps/x86/libc-start.h | 54 ++++++++++++++- - sysdeps/x86_64/dl-machine.h | 12 +++- - sysdeps/x86_64/x32/dl-machine.h | 7 +- - 11 files changed, 180 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..634c885d33 100644 ---- a/sysdeps/unix/sysv/linux/x86/dl-cet.h -+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h -@@ -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 inline unsigned int __attribute__ ((always_inline)) -+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 6c0d6c100d..45bc7fcac3 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -836,57 +836,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 8b911fd931..7f37244d37 100644 ---- a/sysdeps/x86/dl-cet.c -+++ b/sysdeps/x86/dl-cet.c -@@ -172,40 +172,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 - -@@ -291,6 +262,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; -@@ -300,17 +280,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; - -@@ -344,6 +316,33 @@ _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) -+ { -+ cet_feature = dl_cet_get_cet_status (); -+ /* Sync GL(dl_x86_feature_1) with kernel. */ -+ GL(dl_x86_feature_1) = cet_feature; -+ if (cet_feature) -+ { -+ 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); -+ } -+ } -+} -+ - #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 40b8129d6a..e6a2424682 100644 ---- a/sysdeps/x86/include/cpu-features.h -+++ b/sysdeps/x86/include/cpu-features.h -@@ -958,6 +958,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..856230daeb 100644 ---- a/sysdeps/x86/libc-start.h -+++ b/sysdeps/x86/libc-start.h -@@ -19,7 +19,57 @@ - #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. */ -+ struct cpu_features *cpu_features -+ = (struct 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\ -diff --git a/sysdeps/x86_64/x32/dl-machine.h b/sysdeps/x86_64/x32/dl-machine.h -index 648a11f926..d8598b3e9c 100644 ---- a/sysdeps/x86_64/x32/dl-machine.h -+++ b/sysdeps/x86_64/x32/dl-machine.h -@@ -45,13 +45,16 @@ _start:\n\ - _dl_start_user:\n\ - # Save the user entry point address in %r12.\n\ - movl %eax, %r12d\n\ -+ # Save %rsp value in %r13.\n\ -+ movl %esp, %r13d\n\ -+"\ -+ RTLD_START_ENABLE_X86_FEATURES \ -+"\ - # 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\ --- -2.40.1 - diff --git a/v2-0015-x86-cet-Check-feature_1-in-TCB-for-active-IBT-and.patch b/v2-0015-x86-cet-Check-feature_1-in-TCB-for-active-IBT-and.patch deleted file mode 100644 index 88ed83a..0000000 --- a/v2-0015-x86-cet-Check-feature_1-in-TCB-for-active-IBT-and.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 7b3c43e6b089eb7efefdbb32b99da6b1ab469151 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Tue, 11 Apr 2023 14:03:43 -0700 -Subject: [PATCH v2 15/15] 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. ---- - 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 6555f9b91d..c9b6ee1766 100644 ---- a/sysdeps/x86/bits/platform/x86.h -+++ b/sysdeps/x86/bits/platform/x86.h -@@ -326,3 +326,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.40.1 -