From 394df3815e8ceec750fd06583eee4896174ce808 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 24 Jul 2018 12:23:03 -0700 Subject: x86/CET: Extend arch_prctl syscall for CET control CET arch_prctl bits should be defined in from Linux kernel header files. Add x86 for pre-CET kernel header files. Note: sysdeps/unix/sysv/linux/x86/include/asm/prctl.h should be removed if 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 * sysdeps/unix/sysv/linux/x86/include/asm/prctl.h: New file. * sysdeps/unix/sysv/linux/x86/cpu-features.c: Include and . (get_cet_status): Call arch_prctl with ARCH_CET_STATUS. * sysdeps/unix/sysv/linux/x86/dl-cet.h: Include and . (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 . --- ChangeLog | 14 +++++++++++ sysdeps/unix/sysv/linux/x86/cpu-features.c | 8 +++++++ sysdeps/unix/sysv/linux/x86/dl-cet.h | 30 ++++++++++++++++++----- sysdeps/unix/sysv/linux/x86/include/asm/prctl.h | 32 +++++++++++++++++++++++++ sysdeps/x86/libc-start.c | 3 +++ 5 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/x86/include/asm/prctl.h diff --git a/ChangeLog b/ChangeLog index d6f3dbe1ed..28d21257d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2018-07-24 H.J. Lu + + * sysdeps/unix/sysv/linux/x86/include/asm/prctl.h: New file. + * sysdeps/unix/sysv/linux/x86/cpu-features.c: Include + and . + (get_cet_status): Call arch_prctl with ARCH_CET_STATUS. + * sysdeps/unix/sysv/linux/x86/dl-cet.h: Include + and . + (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 . + 2018-07-24 Florian Weimer * sysdeps/unix/sysv/linux/sh/kernel-features.h (__ASSUME_STATX): diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c index 7c9df9b794..8566a265b8 100644 --- a/sysdeps/unix/sysv/linux/x86/cpu-features.c +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c @@ -17,9 +17,17 @@ . */ #if CET_ENABLED +# include +# include + 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; } diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h index ae81e2f2ca..3fbcfebed5 100644 --- a/sysdeps/unix/sysv/linux/x86/dl-cet.h +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h @@ -15,23 +15,41 @@ License along with the GNU C Library; if not, see . */ +#include +#include + 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 index 0000000000..f67f3299b9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h @@ -0,0 +1,32 @@ +/* FIXME: CET arch_prctl bits should come from the kernel header files. + This file should be removed if from the required kernel + header files contains CET arch_prctl bits. */ + +#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 +/* 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 */ diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c index 43aba9d061..eb5335c154 100644 --- a/sysdeps/x86/libc-start.c +++ b/sysdeps/x86/libc-start.c @@ -16,6 +16,9 @@ . */ #ifndef SHARED +/* Define I386_USE_SYSENTER to support syscall during startup in static + PIE. */ +# include # include # include # include -- cgit v1.2.3