glibc/v2-0015-x86-cet-Check-feature_1-in-TCB-for-active-IBT-and.patch
Siddhesh Poyarekar 144f612406 Shadow stack userspace support
Downstream only and disabled by default.
2023-06-08 13:31:34 -04:00

90 lines
2.8 KiB
Diff

From 7b3c43e6b089eb7efefdbb32b99da6b1ab469151 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
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
<https://www.gnu.org/licenses/>. */
-
+#include <assert.h>
+#include <tcb-offsets.h>
#include <ldsodefs.h>
+#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