]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86/CET: Extend arch_prctl syscall for CET control
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 24 Jul 2018 19:23:03 +0000 (12:23 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 24 Jul 2018 19:23:17 +0000 (12:23 -0700)
CET arch_prctl bits should be defined in <asm/prctl.h> from Linux kernel
header files.  Add x86 <include/asm/prctl.h> for pre-CET kernel header
files.

Note: sysdeps/unix/sysv/linux/x86/include/asm/prctl.h should be removed
if <asm/prctl.h> from the required kernel header files contains CET
arch_prctl bits.

 /* 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
 /* Return legacy region bitmap info in unsigned long long *addr:
     address: addr[0].
     size: addr[1].
  */
 # define ARCH_CET_LEGACY_BITMAP 0x3005

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* sysdeps/unix/sysv/linux/x86/include/asm/prctl.h: New file.
* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
<sys/prctl.h> and <asm/prctl.h>.
(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include <sys/prctl.h>
and <asm/prctl.h>.
(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
ARCH_CET_LEGACY_BITMAP.
(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
* sysdeps/x86/libc-start.c: Include <startup.h>.

ChangeLog
sysdeps/unix/sysv/linux/x86/cpu-features.c
sysdeps/unix/sysv/linux/x86/dl-cet.h
sysdeps/unix/sysv/linux/x86/include/asm/prctl.h [new file with mode: 0644]
sysdeps/x86/libc-start.c

index d6f3dbe1ed24896f9015695e60d69cc3a6d09905..28d21257d77424ecc449a477aae2e343fafc302f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2018-07-24  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * sysdeps/unix/sysv/linux/x86/include/asm/prctl.h: New file.
+       * sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
+       <sys/prctl.h> and <asm/prctl.h>.
+       (get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
+       * sysdeps/unix/sysv/linux/x86/dl-cet.h: Include <sys/prctl.h>
+       and <asm/prctl.h>.
+       (dl_cet_allocate_legacy_bitmap): Call arch_prctl with
+       ARCH_CET_LEGACY_BITMAP.
+       (dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
+       (dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
+       * sysdeps/x86/libc-start.c: Include <startup.h>.
+
 2018-07-24  Florian Weimer  <fweimer@redhat.com>
 
        * sysdeps/unix/sysv/linux/sh/kernel-features.h (__ASSUME_STATX):
index 7c9df9b7947135727800786e660629e60f5dbfe2..8566a265b87a3f45b0717348ab19a83862d61a9e 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #if CET_ENABLED
+# include <sys/prctl.h>
+# include <asm/prctl.h>
+
 static inline int __attribute__ ((always_inline))
 get_cet_status (void)
 {
+  unsigned long long cet_status[3];
+  INTERNAL_SYSCALL_DECL (err);
+  if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
+                       cet_status) == 0)
+    return cet_status[0];
   return 0;
 }
 
index ae81e2f2ca4bd5ae08414469cf2c53b931bf3b63..3fbcfebed5d1619c01c2cc349148d03d9dcebe31 100644 (file)
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sys/prctl.h>
+#include <asm/prctl.h>
+
 static inline int __attribute__ ((always_inline))
 dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  /* Allocate legacy bitmap.  */
+  INTERNAL_SYSCALL_DECL (err);
+#ifdef __LP64__
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
+                                ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
+#else
+  unsigned long long legacy_bitmap_u64[2];
+  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
+                             ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
+  if (res == 0)
+    {
+      legacy_bitmap[0] = legacy_bitmap_u64[0];
+      legacy_bitmap[1] = legacy_bitmap_u64[1];
+    }
+  return res;
+#endif
 }
 
 static inline int __attribute__ ((always_inline))
 dl_cet_disable_cet (unsigned int cet_feature)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  INTERNAL_SYSCALL_DECL (err);
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE,
+                                cet_feature);
 }
 
 static inline int __attribute__ ((always_inline))
 dl_cet_lock_cet (void)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  INTERNAL_SYSCALL_DECL (err);
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0);
 }
diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
new file mode 100644 (file)
index 0000000..f67f329
--- /dev/null
@@ -0,0 +1,32 @@
+/* FIXME: CET arch_prctl bits should come from the kernel header files.
+   This file should be removed if <asm/prctl.h> from the required kernel
+   header files contains CET arch_prctl bits.  */
+
+#include_next <asm/prctl.h>
+
+#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
+/* Return legacy region bitmap info in unsigned long long *addr:
+     address: addr[0].
+     size: addr[1].
+ */
+# define ARCH_CET_LEGACY_BITMAP        0x3005
+#endif /* ARCH_CET_STATUS */
index 43aba9d061350c5a896a9523b8569c85e8c8cfad..eb5335c154096384ec4c2eb29dbccf93da033ece 100644 (file)
@@ -16,6 +16,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef SHARED
+/* Define I386_USE_SYSENTER to support syscall during startup in static
+   PIE.  */
+# include <startup.h>
 # include <ldsodefs.h>
 # include <cpu-features.h>
 # include <cpu-features.c>