LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/7] Control Flow Enforcement - Part (4)
@ 2018-06-07 14:38 Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking Yu-cheng Yu
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz
  Cc: Yu-cheng Yu

This series introduces CET - indirect branch tracking

The major task of indirect branch tracking is for the compiler to
insert the ENDBR instructions at all valid branch targets.

The kernel provides:
	CPUID enumeration and feature setup;
	Legacy bitmap allocation;
	Some basic supporting routines.

In this patch, there are also a CET command-line utility and
PTRACE support.

H.J. Lu (2):
  x86: Insert endbr32/endbr64 to vDSO
  tools: Add cetcmd

Yu-cheng Yu (5):
  x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking
  x86/cet: User-mode indirect branch tracking support
  mm/mmap: Add IBT bitmap size to address space limit check
  x86/cet: add arcp_prctl functions for indirect branch tracking
  x86/cet: Add PTRACE interface for CET

 arch/x86/Kconfig                               |  12 +++
 arch/x86/entry/vdso/.gitignore                 |   4 +
 arch/x86/entry/vdso/Makefile                   |  34 +++++++
 arch/x86/entry/vdso/endbr.sh                   |  32 ++++++
 arch/x86/include/asm/cet.h                     |   9 ++
 arch/x86/include/asm/disabled-features.h       |   8 +-
 arch/x86/include/asm/fpu/regset.h              |   7 +-
 arch/x86/include/uapi/asm/prctl.h              |   1 +
 arch/x86/include/uapi/asm/resource.h           |   5 +
 arch/x86/kernel/cet.c                          |  73 ++++++++++++++
 arch/x86/kernel/cet_prctl.c                    |  54 +++++++++-
 arch/x86/kernel/cpu/common.c                   |  20 +++-
 arch/x86/kernel/elf.c                          |  19 +++-
 arch/x86/kernel/fpu/regset.c                   |  41 ++++++++
 arch/x86/kernel/process.c                      |   2 +
 arch/x86/kernel/ptrace.c                       |  16 +++
 include/uapi/asm-generic/resource.h            |   3 +
 include/uapi/linux/elf.h                       |   1 +
 mm/mmap.c                                      |   8 +-
 tools/Makefile                                 |  13 +--
 tools/arch/x86/include/uapi/asm/elf_property.h |  16 +++
 tools/arch/x86/include/uapi/asm/prctl.h        |  33 ++++++
 tools/cet/.gitignore                           |   1 +
 tools/cet/Makefile                             |  11 ++
 tools/cet/cetcmd.c                             | 134 +++++++++++++++++++++++++
 tools/include/uapi/asm/elf_property.h          |   4 +
 tools/include/uapi/asm/prctl.h                 |   4 +
 27 files changed, 549 insertions(+), 16 deletions(-)
 create mode 100644 arch/x86/entry/vdso/endbr.sh
 create mode 100644 tools/arch/x86/include/uapi/asm/elf_property.h
 create mode 100644 tools/arch/x86/include/uapi/asm/prctl.h
 create mode 100644 tools/cet/.gitignore
 create mode 100644 tools/cet/Makefile
 create mode 100644 tools/cet/cetcmd.c
 create mode 100644 tools/include/uapi/asm/elf_property.h
 create mode 100644 tools/include/uapi/asm/prctl.h

-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 16:43   ` Randy Dunlap
  2018-06-07 14:38 ` [PATCH 2/7] x86/cet: User-mode indirect branch tracking support Yu-cheng Yu
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz
  Cc: Yu-cheng Yu

The user-mode indirect branch tracking support is done mostly by
GCC to insert ENDBR64/ENDBR32 instructions at branch targets.
The kernel provides CPUID enumeration, feature MSR setup and
the allocation of legacy bitmap.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 arch/x86/Kconfig | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 24339a5299da..27bfbd137fbe 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1953,6 +1953,18 @@ config X86_INTEL_SHADOW_STACK_USER
 
 	  If unsure, say y.
 
+config X86_INTEL_BRANCH_TRACKING_USER
+	prompt "Intel Indirect Branch Tracking for user-mode"
+	def_bool n
+	depends on CPU_SUP_INTEL && X86_64
+	select X86_INTEL_CET
+	select ARCH_HAS_PROGRAM_PROPERTIES
+	---help---
+	  Indirect Branch Tracking provides hardware protection against return-/jmp-
+	  oriented programing attacks.
+
+	  If unsure, say y
+
 config EFI
 	bool "EFI runtime service support"
 	depends on ACPI
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/7] x86/cet: User-mode indirect branch tracking support
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 3/7] mm/mmap: Add IBT bitmap size to address space limit check Yu-cheng Yu
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz
  Cc: Yu-cheng Yu

Add user-mode indirect branch tracking enabling/disabling
and supporting routines.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 arch/x86/include/asm/cet.h               |  8 ++++
 arch/x86/include/asm/disabled-features.h |  8 +++-
 arch/x86/kernel/cet.c                    | 73 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/common.c             | 20 ++++++++-
 arch/x86/kernel/elf.c                    | 15 ++++++-
 arch/x86/kernel/process.c                |  1 +
 6 files changed, 122 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cet.h b/arch/x86/include/asm/cet.h
index a2a53fe4d5e6..d07bdeb27db4 100644
--- a/arch/x86/include/asm/cet.h
+++ b/arch/x86/include/asm/cet.h
@@ -13,7 +13,10 @@ struct cet_stat {
 	unsigned long	shstk_base;
 	unsigned long	shstk_size;
 	unsigned long	exec_shstk_size;
+	unsigned long	ibt_bitmap_addr;
+	unsigned long	ibt_bitmap_size;
 	unsigned int	shstk_enabled:1;
+	unsigned int	ibt_enabled:1;
 	unsigned int	locked:1;
 	unsigned int	exec_shstk:2;
 };
@@ -29,6 +32,9 @@ void cet_disable_shstk(void);
 void cet_disable_free_shstk(struct task_struct *p);
 int cet_restore_signal(unsigned long ssp);
 int cet_setup_signal(int ia32, unsigned long addr);
+int cet_setup_ibt(void);
+int cet_setup_ibt_bitmap(void);
+void cet_disable_ibt(void);
 #else
 static inline int prctl_cet(int option, unsigned long arg2) { return 0; }
 static inline unsigned long cet_get_shstk_ptr(void) { return 0; }
@@ -41,6 +47,8 @@ static inline void cet_disable_shstk(void) {}
 static inline void cet_disable_free_shstk(struct task_struct *p) {}
 static inline int cet_restore_signal(unsigned long ssp) { return 0; }
 static inline int cet_setup_signal(int ia32, unsigned long addr) { return 0; }
+static inline int cet_setup_ibt(void) { return 0; }
+static inline void cet_disable_ibt(void) {}
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
index 3624a11e5ba6..ce5bdaf0f1ff 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -62,6 +62,12 @@
 #define DISABLE_SHSTK	(1<<(X86_FEATURE_SHSTK & 31))
 #endif
 
+#ifdef CONFIG_X86_INTEL_BRANCH_TRACKING_USER
+#define DISABLE_IBT	0
+#else
+#define DISABLE_IBT	(1<<(X86_FEATURE_IBT & 31))
+#endif
+
 /*
  * Make sure to add features to the correct mask
  */
@@ -72,7 +78,7 @@
 #define DISABLED_MASK4	(DISABLE_PCID)
 #define DISABLED_MASK5	0
 #define DISABLED_MASK6	0
-#define DISABLED_MASK7	(DISABLE_PTI)
+#define DISABLED_MASK7	(DISABLE_PTI|DISABLE_IBT)
 #define DISABLED_MASK8	0
 #define DISABLED_MASK9	(DISABLE_MPX)
 #define DISABLED_MASK10	0
diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c
index 1b7089dcf1ea..4df4b583311f 100644
--- a/arch/x86/kernel/cet.c
+++ b/arch/x86/kernel/cet.c
@@ -12,6 +12,8 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/sched/signal.h>
+#include <linux/vmalloc.h>
+#include <linux/bitops.h>
 #include <asm/msr.h>
 #include <asm/user.h>
 #include <asm/fpu/xstate.h>
@@ -222,3 +224,74 @@ int cet_setup_signal(int ia32, unsigned long rstor_addr)
 
 	return cet_push_shstk(ia32, ssp, rstor_addr);
 }
+
+static unsigned long ibt_mmap(unsigned long addr, unsigned long len)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long populate;
+
+	down_write(&mm->mmap_sem);
+	addr = do_mmap(NULL, addr, len, PROT_READ | PROT_WRITE,
+		       MAP_ANONYMOUS | MAP_PRIVATE,
+		       VM_DONTDUMP, 0, &populate, NULL);
+	up_write(&mm->mmap_sem);
+
+	if (populate)
+		mm_populate(addr, populate);
+
+	return addr;
+}
+
+int cet_setup_ibt(void)
+{
+	u64 r;
+
+	if (!cpu_feature_enabled(X86_FEATURE_IBT))
+		return -EOPNOTSUPP;
+
+	rdmsrl(MSR_IA32_U_CET, r);
+	r |= (MSR_IA32_CET_ENDBR_EN | MSR_IA32_CET_NO_TRACK_EN);
+	wrmsrl(MSR_IA32_U_CET, r);
+	current->thread.cet.ibt_enabled = 1;
+	return 0;
+}
+
+int cet_setup_ibt_bitmap(void)
+{
+	u64 r;
+	unsigned long bitmap;
+	unsigned long size;
+
+	if (!cpu_feature_enabled(X86_FEATURE_IBT))
+		return -EOPNOTSUPP;
+
+	size = TASK_SIZE / PAGE_SIZE / BITS_PER_BYTE;
+	bitmap = ibt_mmap(0, size);
+
+	if (bitmap >= TASK_SIZE)
+		return -ENOMEM;
+
+	bitmap &= PAGE_MASK;
+
+	rdmsrl(MSR_IA32_U_CET, r);
+	r |= (MSR_IA32_CET_LEG_IW_EN | bitmap);
+	wrmsrl(MSR_IA32_U_CET, r);
+
+	current->thread.cet.ibt_bitmap_addr = bitmap;
+	current->thread.cet.ibt_bitmap_size = size;
+	return 0;
+}
+
+void cet_disable_ibt(void)
+{
+	u64 r;
+
+	if (!cpu_feature_enabled(X86_FEATURE_IBT))
+		return;
+
+	rdmsrl(MSR_IA32_U_CET, r);
+	r &= ~(MSR_IA32_CET_ENDBR_EN | MSR_IA32_CET_LEG_IW_EN |
+	       MSR_IA32_CET_NO_TRACK_EN);
+	wrmsrl(MSR_IA32_U_CET, r);
+	current->thread.cet.ibt_enabled = 0;
+}
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f54fabdaef60..4041d6b94455 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -403,7 +403,8 @@ __setup("nopku", setup_disable_pku);
 
 static __always_inline void setup_cet(struct cpuinfo_x86 *c)
 {
-	if (cpu_feature_enabled(X86_FEATURE_SHSTK))
+	if (cpu_feature_enabled(X86_FEATURE_SHSTK) ||
+	    cpu_feature_enabled(X86_FEATURE_IBT))
 		cr4_set_bits(X86_CR4_CET);
 }
 
@@ -424,6 +425,23 @@ static __init int setup_disable_shstk(char *s)
 __setup("noshstk", setup_disable_shstk);
 #endif
 
+#ifdef CONFIG_X86_INTEL_BRANCH_TRACKING_USER
+static __init int setup_disable_ibt(char *s)
+{
+	/* require an exact match without trailing characters */
+	if (strlen(s))
+		return 0;
+
+	if (!boot_cpu_has(X86_FEATURE_IBT))
+		return 1;
+
+	setup_clear_cpu_cap(X86_FEATURE_IBT);
+	pr_info("x86: 'noibt' specified, disabling Branch Tracking\n");
+	return 1;
+}
+__setup("noibt", setup_disable_ibt);
+#endif
+
 /*
  * Some CPU features depend on higher CPUID levels, which may not always
  * be available due to CPUID level capping or broken virtualization
diff --git a/arch/x86/kernel/elf.c b/arch/x86/kernel/elf.c
index de08d41971f6..a3995c8c2fc2 100644
--- a/arch/x86/kernel/elf.c
+++ b/arch/x86/kernel/elf.c
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/string.h>
+#include <linux/compat.h>
 
 #define ELF_NOTE_DESC_OFFSET(n, align) \
 	round_up(sizeof(*n) + n->n_namesz, (align))
@@ -183,7 +184,8 @@ int arch_setup_features(void *ehdr_p, void *phdr_p,
 
 	struct elf64_hdr *ehdr64 = ehdr_p;
 
-	if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
+	if (!cpu_feature_enabled(X86_FEATURE_SHSTK) &&
+	    !cpu_feature_enabled(X86_FEATURE_IBT))
 		return 0;
 
 	if (ehdr64->e_ident[EI_CLASS] == ELFCLASS64) {
@@ -211,6 +213,9 @@ int arch_setup_features(void *ehdr_p, void *phdr_p,
 	current->thread.cet.shstk_enabled = 0;
 	current->thread.cet.shstk_base = 0;
 	current->thread.cet.shstk_size = 0;
+	current->thread.cet.ibt_enabled = 0;
+	current->thread.cet.ibt_bitmap_addr = 0;
+	current->thread.cet.ibt_bitmap_size = 0;
 	current->thread.cet.locked = 0;
 	if (cpu_feature_enabled(X86_FEATURE_SHSTK)) {
 		int exec = current->thread.cet.exec_shstk;
@@ -224,6 +229,14 @@ int arch_setup_features(void *ehdr_p, void *phdr_p,
 		}
 	}
 
+	if (cpu_feature_enabled(X86_FEATURE_IBT)) {
+		if (ibt) {
+			err = cet_setup_ibt();
+			if (err < 0)
+				goto out;
+		}
+	}
+
 	/*
 	 * Lockout CET features if no interpreter
 	 */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 54ad1863c6d2..9bec164e7958 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -139,6 +139,7 @@ void flush_thread(void)
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
 
 	cet_disable_shstk();
+	cet_disable_ibt();
 	fpu__clear(&tsk->thread.fpu);
 }
 
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 3/7] mm/mmap: Add IBT bitmap size to address space limit check
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 2/7] x86/cet: User-mode indirect branch tracking support Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 18:39   ` Andy Lutomirski
  2018-06-07 14:38 ` [PATCH 4/7] x86/cet: add arcp_prctl functions for indirect branch tracking Yu-cheng Yu
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz
  Cc: Yu-cheng Yu

The indirect branch tracking legacy bitmap takes a large address
space.  This causes may_expand_vm() failure on the address limit
check.  For a IBT-enabled task, add the bitmap size to the
address limit.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 arch/x86/include/uapi/asm/resource.h | 5 +++++
 include/uapi/asm-generic/resource.h  | 3 +++
 mm/mmap.c                            | 8 +++++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/uapi/asm/resource.h b/arch/x86/include/uapi/asm/resource.h
index 04bc4db8921b..0741b2a6101a 100644
--- a/arch/x86/include/uapi/asm/resource.h
+++ b/arch/x86/include/uapi/asm/resource.h
@@ -1 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+#ifdef CONFIG_X86_INTEL_CET
+#define rlimit_as_extra() current->thread.cet.ibt_bitmap_size
+#endif
+
 #include <asm-generic/resource.h>
diff --git a/include/uapi/asm-generic/resource.h b/include/uapi/asm-generic/resource.h
index f12db7a0da64..8a7608a09700 100644
--- a/include/uapi/asm-generic/resource.h
+++ b/include/uapi/asm-generic/resource.h
@@ -58,5 +58,8 @@
 # define RLIM_INFINITY		(~0UL)
 #endif
 
+#ifndef rlimit_as_extra
+#define rlimit_as_extra() 0
+#endif
 
 #endif /* _UAPI_ASM_GENERIC_RESOURCE_H */
diff --git a/mm/mmap.c b/mm/mmap.c
index e7d1fcb7ec58..5c07f052bed7 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3255,7 +3255,13 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
  */
 bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages)
 {
-	if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT)
+	unsigned long as_limit = rlimit(RLIMIT_AS);
+	unsigned long as_limit_plus = as_limit + rlimit_as_extra();
+
+	if (as_limit_plus > as_limit)
+		as_limit = as_limit_plus;
+
+	if (mm->total_vm + npages > as_limit >> PAGE_SHIFT)
 		return false;
 
 	if (is_data_mapping(flags) &&
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 4/7] x86/cet: add arcp_prctl functions for indirect branch tracking
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
                   ` (2 preceding siblings ...)
  2018-06-07 14:38 ` [PATCH 3/7] mm/mmap: Add IBT bitmap size to address space limit check Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO Yu-cheng Yu
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz
  Cc: Yu-cheng Yu

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 arch/x86/include/asm/cet.h        |  1 +
 arch/x86/include/uapi/asm/prctl.h |  1 +
 arch/x86/kernel/cet_prctl.c       | 54 ++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/elf.c             | 12 ++++++---
 arch/x86/kernel/process.c         |  1 +
 5 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/cet.h b/arch/x86/include/asm/cet.h
index d07bdeb27db4..5b71a2b44eb1 100644
--- a/arch/x86/include/asm/cet.h
+++ b/arch/x86/include/asm/cet.h
@@ -19,6 +19,7 @@ struct cet_stat {
 	unsigned int	ibt_enabled:1;
 	unsigned int	locked:1;
 	unsigned int	exec_shstk:2;
+	unsigned int	exec_ibt:2;
 };
 
 #ifdef CONFIG_X86_INTEL_CET
diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h
index f9965403b655..fef476d2d2f6 100644
--- a/arch/x86/include/uapi/asm/prctl.h
+++ b/arch/x86/include/uapi/asm/prctl.h
@@ -20,6 +20,7 @@
 #define ARCH_CET_EXEC		0x3004
 #define ARCH_CET_ALLOC_SHSTK	0x3005
 #define ARCH_CET_PUSH_SHSTK	0x3006
+#define ARCH_CET_LEGACY_BITMAP	0x3007
 
 /*
  * Settings for ARCH_CET_EXEC
diff --git a/arch/x86/kernel/cet_prctl.c b/arch/x86/kernel/cet_prctl.c
index 326996e2ea80..948f7ba98dc2 100644
--- a/arch/x86/kernel/cet_prctl.c
+++ b/arch/x86/kernel/cet_prctl.c
@@ -19,6 +19,7 @@
  * ARCH_CET_EXEC: set default features for exec()
  * ARCH_CET_ALLOC_SHSTK: allocate shadow stack
  * ARCH_CET_PUSH_SHSTK: put a return address on shadow stack
+ * ARCH_CET_LEGACY_BITMAP: allocate legacy bitmap
  */
 
 static int handle_get_status(unsigned long arg2)
@@ -28,8 +29,12 @@ static int handle_get_status(unsigned long arg2)
 
 	if (current->thread.cet.shstk_enabled)
 		features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+	if (current->thread.cet.ibt_enabled)
+		features |= GNU_PROPERTY_X86_FEATURE_1_IBT;
 	if (current->thread.cet.exec_shstk == CET_EXEC_ALWAYS_ON)
 		cet_exec |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+	if (current->thread.cet.exec_ibt == CET_EXEC_ALWAYS_ON)
+		cet_exec |= GNU_PROPERTY_X86_FEATURE_1_IBT;
 	shstk_size = current->thread.cet.exec_shstk_size;
 
 	if (in_compat_syscall()) {
@@ -94,9 +99,18 @@ static int handle_set_exec(unsigned long arg2)
 			return -EPERM;
 	}
 
+	if (features & GNU_PROPERTY_X86_FEATURE_1_IBT) {
+		if (!cpu_feature_enabled(X86_FEATURE_IBT))
+			return -EINVAL;
+		if ((current->thread.cet.exec_ibt == CET_EXEC_ALWAYS_ON) &&
+		    (cet_exec != CET_EXEC_ALWAYS_ON))
+			return -EPERM;
+	}
+
 	if (features & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
 		current->thread.cet.exec_shstk = cet_exec;
-
+	if (features & GNU_PROPERTY_X86_FEATURE_1_IBT)
+		current->thread.cet.exec_ibt = cet_exec;
 	current->thread.cet.exec_shstk_size = shstk_size;
 	return 0;
 }
@@ -167,9 +181,36 @@ static int handle_alloc_shstk(unsigned long arg2)
 	return 0;
 }
 
+static int handle_bitmap(unsigned long arg2)
+{
+	unsigned long addr, size;
+
+	if (current->thread.cet.ibt_enabled) {
+		if (!current->thread.cet.ibt_bitmap_addr)
+			cet_setup_ibt_bitmap();
+		addr = current->thread.cet.ibt_bitmap_addr;
+		size = current->thread.cet.ibt_bitmap_size;
+	} else {
+		addr = 0;
+		size = 0;
+	}
+
+	if (in_compat_syscall()) {
+		if (put_user(addr, (unsigned int __user *)arg2) ||
+		    put_user(size, (unsigned int __user *)arg2 + 1))
+			return -EFAULT;
+	} else {
+		if (put_user(addr, (unsigned long __user *)arg2) ||
+		    put_user(size, (unsigned long __user *)arg2 + 1))
+		return -EFAULT;
+	}
+	return 0;
+}
+
 int prctl_cet(int option, unsigned long arg2)
 {
-	if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
+	if (!cpu_feature_enabled(X86_FEATURE_SHSTK) &&
+	    !cpu_feature_enabled(X86_FEATURE_IBT))
 		return -EINVAL;
 
 	switch (option) {
@@ -181,7 +222,8 @@ int prctl_cet(int option, unsigned long arg2)
 			return -EPERM;
 		if (arg2 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
 			cet_disable_free_shstk(current);
-
+		if (arg2 & GNU_PROPERTY_X86_FEATURE_1_IBT)
+			cet_disable_ibt();
 		return 0;
 
 	case ARCH_CET_LOCK:
@@ -197,6 +239,12 @@ int prctl_cet(int option, unsigned long arg2)
 	case ARCH_CET_PUSH_SHSTK:
 		return handle_push_shstk(arg2);
 
+	/*
+	 * Allocate legacy bitmap and return address & size to user.
+	 */
+	case ARCH_CET_LEGACY_BITMAP:
+		return handle_bitmap(arg2);
+
 	default:
 		return -EINVAL;
 	}
diff --git a/arch/x86/kernel/elf.c b/arch/x86/kernel/elf.c
index a3995c8c2fc2..c2a89f3c7186 100644
--- a/arch/x86/kernel/elf.c
+++ b/arch/x86/kernel/elf.c
@@ -230,10 +230,14 @@ int arch_setup_features(void *ehdr_p, void *phdr_p,
 	}
 
 	if (cpu_feature_enabled(X86_FEATURE_IBT)) {
-		if (ibt) {
-			err = cet_setup_ibt();
-			if (err < 0)
-				goto out;
+		int exec = current->thread.cet.exec_ibt;
+
+		if (exec != CET_EXEC_ALWAYS_OFF) {
+			if (ibt || (exec == CET_EXEC_ALWAYS_ON)) {
+				err = cet_setup_ibt();
+				if (err < 0)
+					goto out;
+			}
 		}
 	}
 
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 9bec164e7958..c69576b4abd1 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -801,6 +801,7 @@ long do_arch_prctl_common(struct task_struct *task, int option,
 	case ARCH_CET_EXEC:
 	case ARCH_CET_ALLOC_SHSTK:
 	case ARCH_CET_PUSH_SHSTK:
+	case ARCH_CET_LEGACY_BITMAP:
 		return prctl_cet(option, cpuid_enabled);
 	}
 
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
                   ` (3 preceding siblings ...)
  2018-06-07 14:38 ` [PATCH 4/7] x86/cet: add arcp_prctl functions for indirect branch tracking Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 20:50   ` Andy Lutomirski
  2018-06-07 14:38 ` [PATCH 6/7] tools: Add cetcmd Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 7/7] x86/cet: Add PTRACE interface for CET Yu-cheng Yu
  6 siblings, 1 reply; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz

From: "H.J. Lu" <hjl.tools@gmail.com>

When Intel indirect branch tracking is enabled, functions in vDSO which
may be called indirectly should have endbr32 or endbr64 as the first
instruction.  We try to compile vDSO with -fcf-protection=branch -mibt
if possible.  Otherwise, we insert endbr32 or endbr64 by hand to assembly
codes generated by the compiler.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 arch/x86/entry/vdso/.gitignore |  4 ++++
 arch/x86/entry/vdso/Makefile   | 34 ++++++++++++++++++++++++++++++++++
 arch/x86/entry/vdso/endbr.sh   | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 arch/x86/entry/vdso/endbr.sh

diff --git a/arch/x86/entry/vdso/.gitignore b/arch/x86/entry/vdso/.gitignore
index aae8ffdd5880..552941fdfae0 100644
--- a/arch/x86/entry/vdso/.gitignore
+++ b/arch/x86/entry/vdso/.gitignore
@@ -5,3 +5,7 @@ vdso32-sysenter-syms.lds
 vdso32-int80-syms.lds
 vdso-image-*.c
 vdso2c
+vclock_gettime.S
+vgetcpu.S
+vclock_gettime.asm
+vgetcpu.asm
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index d998a487c9b1..cccafc36a831 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -118,6 +118,40 @@ $(obj)/%-x32.o: $(obj)/%.o FORCE
 
 targets += vdsox32.lds $(vobjx32s-y)
 
+ifdef CONFIG_X86_INTEL_BRANCH_TRACKING_USER
+  ifeq ($(call cc-option-yn, -fcf-protection=branch -mibt), y)
+    $(obj)/vclock_gettime.o $(obj)/vgetcpu.o $(obj)/vdso32/vclock_gettime.o: KBUILD_CFLAGS += -fcf-protection=branch -mibt
+  else
+    endbr := $(srctree)/$(src)/endbr.sh
+    quiet_cmd_endbr = ENDBR $@
+	  cmd_endbr = $(CONFIG_SHELL) '$(endbr)' $< $@
+
+    quiet_cmd_cc_asm_c = CC $(quiet_modtag) $@
+	  cmd_cc_asm_c = $(CC) $(c_flags) $(DISABLE_LTO) -S -o $@ $<
+
+$(obj)/%.asm: $(src)/%.c
+	$(call if_changed_dep,cc_asm_c)
+
+$(obj)/vclock_gettime.S: $(obj)/vclock_gettime.asm
+	$(call if_changed,endbr)
+
+$(obj)/vgetcpu.S: $(obj)/vgetcpu.asm
+	$(call if_changed,endbr)
+
+$(obj)/vclock_gettime.o: $(obj)/vclock_gettime.S
+	 $(call if_changed_rule,as_o_S)
+
+$(obj)/vgetcpu.o: $(obj)/vgetcpu.S
+	 $(call if_changed_rule,as_o_S)
+
+$(obj)/vdso32/vclock_gettime.S: $(obj)/vdso32/vclock_gettime.asm
+	$(call if_changed,endbr)
+
+$(obj)/vdso32/vclock_gettime.o: $(obj)/vdso32/vclock_gettime.S
+	 $(call if_changed_rule,as_o_S)
+  endif
+endif
+
 $(obj)/%.so: OBJCOPYFLAGS := -S
 $(obj)/%.so: $(obj)/%.so.dbg
 	$(call if_changed,objcopy)
diff --git a/arch/x86/entry/vdso/endbr.sh b/arch/x86/entry/vdso/endbr.sh
new file mode 100644
index 000000000000..983dbec182f2
--- /dev/null
+++ b/arch/x86/entry/vdso/endbr.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+in="$1"
+out="$2"
+
+case "$in" in
+*/vdso32/*)
+    endbr=".byte 0xf3,0x0f,0x1e,0xfb"
+    ;;
+*)
+    endbr=".byte 0xf3,0x0f,0x1e,0xfa"
+    ;;
+esac
+
+need_endbr=no
+while IFS= read line ; do
+   case "$line" in
+   __vdso_clock_gettime:|__vdso_getcpu:|__vdso_gettimeofday:|__vdso_time:)
+	need_endbr=yes
+	;;
+   "	."*)
+	;;
+   "	"*)
+	if [ "$need_endbr" = "yes" ]; then
+	    need_endbr=no
+	    echo "	$endbr"
+	fi
+	;;
+   esac
+   echo "$line"
+done < "$in" > "$out"
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 6/7] tools: Add cetcmd
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
                   ` (4 preceding siblings ...)
  2018-06-07 14:38 ` [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 14:38 ` [PATCH 7/7] x86/cet: Add PTRACE interface for CET Yu-cheng Yu
  6 siblings, 0 replies; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz

From: "H.J. Lu" <hjl.tools@gmail.com>

Introduce CET command-line utility.  This utility allows system admin
to enable/disable CET features and set default shadow stack size.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 tools/Makefile                                 |  13 +--
 tools/arch/x86/include/uapi/asm/elf_property.h |  16 +++
 tools/arch/x86/include/uapi/asm/prctl.h        |  33 ++++++
 tools/cet/.gitignore                           |   1 +
 tools/cet/Makefile                             |  11 ++
 tools/cet/cetcmd.c                             | 134 +++++++++++++++++++++++++
 tools/include/uapi/asm/elf_property.h          |   4 +
 tools/include/uapi/asm/prctl.h                 |   4 +
 8 files changed, 210 insertions(+), 6 deletions(-)
 create mode 100644 tools/arch/x86/include/uapi/asm/elf_property.h
 create mode 100644 tools/arch/x86/include/uapi/asm/prctl.h
 create mode 100644 tools/cet/.gitignore
 create mode 100644 tools/cet/Makefile
 create mode 100644 tools/cet/cetcmd.c
 create mode 100644 tools/include/uapi/asm/elf_property.h
 create mode 100644 tools/include/uapi/asm/prctl.h

diff --git a/tools/Makefile b/tools/Makefile
index be02c8b904db..bdca71e61d22 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -10,6 +10,7 @@ help:
 	@echo 'Possible targets:'
 	@echo ''
 	@echo '  acpi                   - ACPI tools'
+	@echo '  cet                    - Intel CET tools'
 	@echo '  cgroup                 - cgroup tools'
 	@echo '  cpupower               - a tool for all things x86 CPU power'
 	@echo '  firewire               - the userspace part of nosy, an IEEE-1394 traffic sniffer'
@@ -59,7 +60,7 @@ acpi: FORCE
 cpupower: FORCE
 	$(call descend,power/$@)
 
-cgroup firewire hv guest spi usb virtio vm bpf iio gpio objtool leds wmi: FORCE
+cet cgroup firewire hv guest spi usb virtio vm bpf iio gpio objtool leds wmi: FORCE
 	$(call descend,$@)
 
 liblockdep: FORCE
@@ -91,7 +92,7 @@ freefall: FORCE
 kvm_stat: FORCE
 	$(call descend,kvm/$@)
 
-all: acpi cgroup cpupower gpio hv firewire liblockdep \
+all: acpi cet cgroup cpupower gpio hv firewire liblockdep \
 		perf selftests spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi
@@ -102,7 +103,7 @@ acpi_install:
 cpupower_install:
 	$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install:
+cet_install cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install:
 	$(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -123,7 +124,7 @@ freefall_install:
 kvm_stat_install:
 	$(call descend,kvm/$(@:_install=),install)
 
-install: acpi_install cgroup_install cpupower_install gpio_install \
+install: acpi_install cet_install cgroup_install cpupower_install gpio_install \
 		hv_install firewire_install iio_install liblockdep_install \
 		perf_install selftests_install turbostat_install usb_install \
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
@@ -136,7 +137,7 @@ acpi_clean:
 cpupower_clean:
 	$(call descend,power/cpupower,clean)
 
-cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean:
+cet_clean cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean:
 	$(call descend,$(@:_clean=),clean)
 
 liblockdep_clean:
@@ -170,7 +171,7 @@ freefall_clean:
 build_clean:
 	$(call descend,build,clean)
 
-clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
+clean: acpi_clean cet_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
 		perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
diff --git a/tools/arch/x86/include/uapi/asm/elf_property.h b/tools/arch/x86/include/uapi/asm/elf_property.h
new file mode 100644
index 000000000000..343a871b8fc1
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/elf_property.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _UAPI_ASM_X86_ELF_PROPERTY_H
+#define _UAPI_ASM_X86_ELF_PROPERTY_H
+
+/*
+ * pr_type
+ */
+#define GNU_PROPERTY_X86_FEATURE_1_AND (0xc0000002)
+
+/*
+ * Bits for GNU_PROPERTY_X86_FEATURE_1_AND
+ */
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK	(0x00000002)
+#define GNU_PROPERTY_X86_FEATURE_1_IBT		(0x00000001)
+
+#endif /* _UAPI_ASM_X86_ELF_PROPERTY_H */
diff --git a/tools/arch/x86/include/uapi/asm/prctl.h b/tools/arch/x86/include/uapi/asm/prctl.h
new file mode 100644
index 000000000000..fef476d2d2f6
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/prctl.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_X86_PRCTL_H
+#define _ASM_X86_PRCTL_H
+
+#define ARCH_SET_GS		0x1001
+#define ARCH_SET_FS		0x1002
+#define ARCH_GET_FS		0x1003
+#define ARCH_GET_GS		0x1004
+
+#define ARCH_GET_CPUID		0x1011
+#define ARCH_SET_CPUID		0x1012
+
+#define ARCH_MAP_VDSO_X32	0x2001
+#define ARCH_MAP_VDSO_32	0x2002
+#define ARCH_MAP_VDSO_64	0x2003
+
+#define ARCH_CET_STATUS		0x3001
+#define ARCH_CET_DISABLE	0x3002
+#define ARCH_CET_LOCK		0x3003
+#define ARCH_CET_EXEC		0x3004
+#define ARCH_CET_ALLOC_SHSTK	0x3005
+#define ARCH_CET_PUSH_SHSTK	0x3006
+#define ARCH_CET_LEGACY_BITMAP	0x3007
+
+/*
+ * Settings for ARCH_CET_EXEC
+ */
+#define CET_EXEC_ELF_PROPERTY	0
+#define CET_EXEC_ALWAYS_OFF	1
+#define CET_EXEC_ALWAYS_ON	2
+#define CET_EXEC_MAX CET_EXEC_ALWAYS_ON
+
+#endif /* _ASM_X86_PRCTL_H */
diff --git a/tools/cet/.gitignore b/tools/cet/.gitignore
new file mode 100644
index 000000000000..bd100f593454
--- /dev/null
+++ b/tools/cet/.gitignore
@@ -0,0 +1 @@
+cetcmd
diff --git a/tools/cet/Makefile b/tools/cet/Makefile
new file mode 100644
index 000000000000..fae42b84d796
--- /dev/null
+++ b/tools/cet/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for CET tools
+
+CFLAGS = -O2 -g -Wall -Wextra -I../include/uapi
+
+all: cetcmd
+%: %.c
+	$(CC) $(CFLAGS) -o $@ $^
+
+clean:
+	$(RM) cetcmd
diff --git a/tools/cet/cetcmd.c b/tools/cet/cetcmd.c
new file mode 100644
index 000000000000..dbbfb5267c1f
--- /dev/null
+++ b/tools/cet/cetcmd.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <error.h>
+#include <asm/elf_property.h>
+#include <asm/prctl.h>
+
+enum command_line_switch {
+	OPTION_ELF_PROPERTY = 150,
+	OPTION_ALWAYS_OFF,
+	OPTION_ALWAYS_ON,
+	OPTION_SHSTK_SIZE
+};
+
+static const struct option options[] = {
+	{"property",	no_argument, 0, OPTION_ELF_PROPERTY},
+	{"off",		no_argument, 0, OPTION_ALWAYS_OFF},
+	{"on",		no_argument, 0, OPTION_ALWAYS_ON},
+	{"shstk-size",	required_argument, 0, OPTION_SHSTK_SIZE},
+	{"feature",	required_argument, 0, 'f'},
+	{"help",	no_argument, 0, 'h'},
+	{0,		no_argument, 0, 0}
+};
+
+__attribute__((__noreturn__))
+static void
+usage(FILE *stream, int exit_status)
+{
+	fprintf(stream, "Usage: %s <option(s)> -- command [args]\n",
+		program_invocation_short_name);
+	fprintf(stream, " Run command with CET features\n");
+	fprintf(stream, " The options are:\n");
+	fprintf(stream,
+		"\t--property                Enable CET features based on ELF property note\n"
+		"\t--off                     Always disable CET features\n"
+		"\t--on                      Always enable CET features\n"
+		"\t-f, --feature [ibt|shstk] Control CET [IBT|SHSTK] feature\n"
+		"\t--shstk-size SIZE         Set shadow stack size\n"
+		"\t-h --help                 Display this information\n");
+
+	exit(exit_status);
+}
+
+extern int arch_prctl(int, unsigned long *);
+
+int
+main(int argc, char *const *argv, char *const *envp)
+{
+	int c;
+	unsigned long values[3] = {0, -1, 0};
+	unsigned long status[3];
+	unsigned long shstk_size = -1;
+	char **args;
+	size_t i, num_of_args;
+
+	while ((c = getopt_long(argc, argv, "f:h",
+				options, (int *) 0)) != EOF) {
+		switch (c) {
+		case OPTION_ELF_PROPERTY:
+			values[1] = CET_EXEC_ELF_PROPERTY;
+			break;
+
+		case OPTION_ALWAYS_OFF:
+			values[1] = CET_EXEC_ALWAYS_OFF;
+			break;
+
+		case OPTION_ALWAYS_ON:
+			values[1] = CET_EXEC_ALWAYS_ON;
+			break;
+
+		case OPTION_SHSTK_SIZE:
+			shstk_size = strtol(optarg, NULL, 0);
+			break;
+
+		case 'f':
+			if (strcasecmp(optarg, "ibt") == 0)
+				values[0] = GNU_PROPERTY_X86_FEATURE_1_IBT;
+			else if (strcasecmp(optarg, "shstk") == 0)
+				values[0] = GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+			else
+				usage(stderr, EXIT_FAILURE);
+			break;
+
+		case 'h':
+			usage(stdout, EXIT_SUCCESS);
+
+		default:
+			usage(stderr, EXIT_FAILURE);
+		}
+	}
+
+	if ((optind + 1) > argc ||
+	    (values[1] == (unsigned long)-1 &&
+	     shstk_size == (unsigned long)-1))
+		usage(stderr, EXIT_FAILURE);
+
+	/* If --shstk-size isn't used, get the current shadow stack size. */
+	if (shstk_size == (unsigned long)-1) {
+		if (arch_prctl(ARCH_CET_STATUS, status) < 0)
+			error(EXIT_FAILURE, errno, "arch_prctl failed\n");
+		shstk_size = status[2];
+	}
+
+	/* If --property/--off/--on aren't used, clear all features. */
+	if (values[1] == (unsigned long)-1) {
+		values[0] = 0;
+		values[1] = 0;
+	} else {
+		if (values[0] == 0)
+			values[0] = (GNU_PROPERTY_X86_FEATURE_1_IBT |
+				     GNU_PROPERTY_X86_FEATURE_1_SHSTK);
+	}
+
+	values[2] = shstk_size;
+	if (arch_prctl(ARCH_CET_EXEC, values) < 0)
+		error(EXIT_FAILURE, errno, "arch_prctl failed\n");
+
+	num_of_args = argc - optind + 1;
+	args = malloc(num_of_args * sizeof(char *));
+	if (args == NULL)
+		error(EXIT_FAILURE, errno, "malloc failed\n");
+
+	for (i = 0; i < num_of_args; i++)
+		args[i] = argv[optind + i];
+	args[i] = NULL;
+
+	return execvpe(argv[optind], args, envp);
+}
diff --git a/tools/include/uapi/asm/elf_property.h b/tools/include/uapi/asm/elf_property.h
new file mode 100644
index 000000000000..1281b4e1a578
--- /dev/null
+++ b/tools/include/uapi/asm/elf_property.h
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if defined(__i386__) || defined(__x86_64__)
+#include "../../arch/x86/include/uapi/asm/elf_property.h"
+#endif
\ No newline at end of file
diff --git a/tools/include/uapi/asm/prctl.h b/tools/include/uapi/asm/prctl.h
new file mode 100644
index 000000000000..b0894b828b06
--- /dev/null
+++ b/tools/include/uapi/asm/prctl.h
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if defined(__i386__) || defined(__x86_64__)
+#include "../../arch/x86/include/uapi/asm/prctl.h"
+#endif
\ No newline at end of file
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] x86/cet: Add PTRACE interface for CET
  2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
                   ` (5 preceding siblings ...)
  2018-06-07 14:38 ` [PATCH 6/7] tools: Add cetcmd Yu-cheng Yu
@ 2018-06-07 14:38 ` Yu-cheng Yu
  2018-06-07 18:32   ` Andy Lutomirski
  6 siblings, 1 reply; 16+ messages in thread
From: Yu-cheng Yu @ 2018-06-07 14:38 UTC (permalink / raw)
  To: linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz
  Cc: Yu-cheng Yu

Add PTRACE interface for CET MSRs.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 arch/x86/include/asm/fpu/regset.h |  7 ++++---
 arch/x86/kernel/fpu/regset.c      | 41 +++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/ptrace.c          | 16 +++++++++++++++
 include/uapi/linux/elf.h          |  1 +
 4 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/fpu/regset.h b/arch/x86/include/asm/fpu/regset.h
index d5bdffb9d27f..edad0d889084 100644
--- a/arch/x86/include/asm/fpu/regset.h
+++ b/arch/x86/include/asm/fpu/regset.h
@@ -7,11 +7,12 @@
 
 #include <linux/regset.h>
 
-extern user_regset_active_fn regset_fpregs_active, regset_xregset_fpregs_active;
+extern user_regset_active_fn regset_fpregs_active, regset_xregset_fpregs_active,
+				cetregs_active;
 extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
-				xstateregs_get;
+				xstateregs_get, cetregs_get;
 extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set,
-				 xstateregs_set;
+				 xstateregs_set, cetregs_set;
 
 /*
  * xstateregs_active == regset_fpregs_active. Please refer to the comment
diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
index bc02f5144b95..7008eb084d36 100644
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -160,6 +160,47 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
 	return ret;
 }
 
+int cetregs_active(struct task_struct *target, const struct user_regset *regset)
+{
+#ifdef CONFIG_X86_INTEL_CET
+	if (target->thread.cet.shstk_enabled || target->thread.cet.ibt_enabled)
+		return regset->n;
+#endif
+	return 0;
+}
+
+int cetregs_get(struct task_struct *target, const struct user_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	struct fpu *fpu = &target->thread.fpu;
+	struct cet_user_state *cetregs;
+
+	if (!boot_cpu_has(X86_FEATURE_SHSTK))
+		return -ENODEV;
+
+	cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_MASK_SHSTK_USER);
+
+	fpu__prepare_read(fpu);
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, cetregs, 0, -1);
+}
+
+int cetregs_set(struct task_struct *target, const struct user_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  const void *kbuf, const void __user *ubuf)
+{
+	struct fpu *fpu = &target->thread.fpu;
+	struct cet_user_state *cetregs;
+
+	if (!boot_cpu_has(X86_FEATURE_SHSTK))
+		return -ENODEV;
+
+	cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_MASK_SHSTK_USER);
+
+	fpu__prepare_write(fpu);
+	return user_regset_copyin(&pos, &count, &kbuf, &ubuf, cetregs, 0, -1);
+}
+
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
 
 /*
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index ed5c4cdf0a34..a4501b8d086a 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -49,7 +49,9 @@ enum x86_regset {
 	REGSET_IOPERM64 = REGSET_XFP,
 	REGSET_XSTATE,
 	REGSET_TLS,
+	REGSET_CET64 = REGSET_TLS,
 	REGSET_IOPERM32,
+	REGSET_CET32,
 };
 
 struct pt_regs_offset {
@@ -1276,6 +1278,13 @@ static struct user_regset x86_64_regsets[] __ro_after_init = {
 		.size = sizeof(long), .align = sizeof(long),
 		.active = ioperm_active, .get = ioperm_get
 	},
+	[REGSET_CET64] = {
+		.core_note_type = NT_X86_CET,
+		.n = sizeof(struct cet_user_state) / sizeof(u64),
+		.size = sizeof(u64), .align = sizeof(u64),
+		.active = cetregs_active, .get = cetregs_get,
+		.set = cetregs_set
+	},
 };
 
 static const struct user_regset_view user_x86_64_view = {
@@ -1331,6 +1340,13 @@ static struct user_regset x86_32_regsets[] __ro_after_init = {
 		.size = sizeof(u32), .align = sizeof(u32),
 		.active = ioperm_active, .get = ioperm_get
 	},
+	[REGSET_CET32] = {
+		.core_note_type = NT_X86_CET,
+		.n = sizeof(struct cet_user_state) / sizeof(u64),
+		.size = sizeof(u64), .align = sizeof(u64),
+		.active = cetregs_active, .get = cetregs_get,
+		.set = cetregs_set
+	},
 };
 
 static const struct user_regset_view user_x86_32_view = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index f69ed8702271..0dd1f9dc6e14 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -401,6 +401,7 @@ typedef struct elf64_shdr {
 #define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
 #define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
 #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
+#define NT_X86_CET	0x203		/* x86 cet state */
 #define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
 #define NT_S390_TIMER	0x301		/* s390 timer register */
 #define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
-- 
2.15.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking
  2018-06-07 14:38 ` [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking Yu-cheng Yu
@ 2018-06-07 16:43   ` Randy Dunlap
  0 siblings, 0 replies; 16+ messages in thread
From: Randy Dunlap @ 2018-06-07 16:43 UTC (permalink / raw)
  To: Yu-cheng Yu, linux-kernel, linux-doc, linux-mm, linux-arch, x86,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, H.J. Lu,
	Vedvyas Shanbhogue, Ravi V. Shankar, Dave Hansen,
	Andy Lutomirski, Jonathan Corbet, Oleg Nesterov, Arnd Bergmann,
	Mike Kravetz

On 06/07/2018 07:38 AM, Yu-cheng Yu wrote:
> The user-mode indirect branch tracking support is done mostly by
> GCC to insert ENDBR64/ENDBR32 instructions at branch targets.
> The kernel provides CPUID enumeration, feature MSR setup and
> the allocation of legacy bitmap.
> 
> Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> ---
>  arch/x86/Kconfig | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 24339a5299da..27bfbd137fbe 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -1953,6 +1953,18 @@ config X86_INTEL_SHADOW_STACK_USER
>  
>  	  If unsure, say y.
>  
> +config X86_INTEL_BRANCH_TRACKING_USER
> +	prompt "Intel Indirect Branch Tracking for user-mode"
> +	def_bool n
> +	depends on CPU_SUP_INTEL && X86_64
> +	select X86_INTEL_CET
> +	select ARCH_HAS_PROGRAM_PROPERTIES
> +	---help---
> +	  Indirect Branch Tracking provides hardware protection against 	
> +	  oriented programing attacks.

	           programming

and please just move the return/jmp parts to the next line also:

	                                             protection against
	  return-/jmp-oriented programming attacks.

> +
> +	  If unsure, say y
> +
>  config EFI
>  	bool "EFI runtime service support"
>  	depends on ACPI
> 


-- 
~Randy

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] x86/cet: Add PTRACE interface for CET
  2018-06-07 14:38 ` [PATCH 7/7] x86/cet: Add PTRACE interface for CET Yu-cheng Yu
@ 2018-06-07 18:32   ` Andy Lutomirski
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Lutomirski @ 2018-06-07 18:32 UTC (permalink / raw)
  To: Yu-cheng Yu
  Cc: LKML, linux-doc, Linux-MM, linux-arch, X86 ML, H. Peter Anvin,
	Thomas Gleixner, Ingo Molnar, H. J. Lu, Shanbhogue, Vedvyas,
	Ravi V. Shankar, Dave Hansen, Jonathan Corbet, Oleg Nesterov,
	Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
>
> Add PTRACE interface for CET MSRs.
>
> Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> ---
>  arch/x86/include/asm/fpu/regset.h |  7 ++++---
>  arch/x86/kernel/fpu/regset.c      | 41 +++++++++++++++++++++++++++++++++++++++
>  arch/x86/kernel/ptrace.c          | 16 +++++++++++++++
>  include/uapi/linux/elf.h          |  1 +
>  4 files changed, 62 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/include/asm/fpu/regset.h b/arch/x86/include/asm/fpu/regset.h
> index d5bdffb9d27f..edad0d889084 100644
> --- a/arch/x86/include/asm/fpu/regset.h
> +++ b/arch/x86/include/asm/fpu/regset.h
> @@ -7,11 +7,12 @@
>
>  #include <linux/regset.h>
>
> -extern user_regset_active_fn regset_fpregs_active, regset_xregset_fpregs_active;
> +extern user_regset_active_fn regset_fpregs_active, regset_xregset_fpregs_active,
> +                               cetregs_active;
>  extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
> -                               xstateregs_get;
> +                               xstateregs_get, cetregs_get;
>  extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set,
> -                                xstateregs_set;
> +                                xstateregs_set, cetregs_set;
>
>  /*
>   * xstateregs_active == regset_fpregs_active. Please refer to the comment
> diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
> index bc02f5144b95..7008eb084d36 100644
> --- a/arch/x86/kernel/fpu/regset.c
> +++ b/arch/x86/kernel/fpu/regset.c
> @@ -160,6 +160,47 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
>         return ret;
>  }
>
> +int cetregs_active(struct task_struct *target, const struct user_regset *regset)
> +{
> +#ifdef CONFIG_X86_INTEL_CET
> +       if (target->thread.cet.shstk_enabled || target->thread.cet.ibt_enabled)
> +               return regset->n;
> +#endif
> +       return 0;
> +}
> +
> +int cetregs_get(struct task_struct *target, const struct user_regset *regset,
> +               unsigned int pos, unsigned int count,
> +               void *kbuf, void __user *ubuf)
> +{
> +       struct fpu *fpu = &target->thread.fpu;
> +       struct cet_user_state *cetregs;
> +
> +       if (!boot_cpu_has(X86_FEATURE_SHSTK))
> +               return -ENODEV;

This whole series has a boot_cpu_has, static_cpu_has, and
cpu_feature_enabled all over.  Please settle on just one, preferably
static_cpu_has.

> +
> +       cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_MASK_SHSTK_USER);
> +
> +       fpu__prepare_read(fpu);
> +       return user_regset_copyout(&pos, &count, &kbuf, &ubuf, cetregs, 0, -1);
> +}
> +
> +int cetregs_set(struct task_struct *target, const struct user_regset *regset,
> +                 unsigned int pos, unsigned int count,
> +                 const void *kbuf, const void __user *ubuf)
> +{
> +       struct fpu *fpu = &target->thread.fpu;
> +       struct cet_user_state *cetregs;
> +
> +       if (!boot_cpu_has(X86_FEATURE_SHSTK))
> +               return -ENODEV;
> +
> +       cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_MASK_SHSTK_USER);
> +
> +       fpu__prepare_write(fpu);
> +       return user_regset_copyin(&pos, &count, &kbuf, &ubuf, cetregs, 0, -1);

Is this called for core dumping on current?  If so, please make sure
it's correct.  (I think it is for get but maybe not for set.)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/7] mm/mmap: Add IBT bitmap size to address space limit check
  2018-06-07 14:38 ` [PATCH 3/7] mm/mmap: Add IBT bitmap size to address space limit check Yu-cheng Yu
@ 2018-06-07 18:39   ` Andy Lutomirski
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Lutomirski @ 2018-06-07 18:39 UTC (permalink / raw)
  To: Yu-cheng Yu
  Cc: LKML, linux-doc, Linux-MM, linux-arch, X86 ML, H. Peter Anvin,
	Thomas Gleixner, Ingo Molnar, H. J. Lu, Shanbhogue, Vedvyas,
	Ravi V. Shankar, Dave Hansen, Jonathan Corbet, Oleg Nesterov,
	Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
>
> The indirect branch tracking legacy bitmap takes a large address
> space.  This causes may_expand_vm() failure on the address limit
> check.  For a IBT-enabled task, add the bitmap size to the
> address limit.
>
> Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> ---
>  arch/x86/include/uapi/asm/resource.h | 5 +++++
>  include/uapi/asm-generic/resource.h  | 3 +++
>  mm/mmap.c                            | 8 +++++++-
>  3 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/uapi/asm/resource.h b/arch/x86/include/uapi/asm/resource.h
> index 04bc4db8921b..0741b2a6101a 100644
> --- a/arch/x86/include/uapi/asm/resource.h
> +++ b/arch/x86/include/uapi/asm/resource.h
> @@ -1 +1,6 @@
> +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
> +#ifdef CONFIG_X86_INTEL_CET
> +#define rlimit_as_extra() current->thread.cet.ibt_bitmap_size
> +#endif
> +
>  #include <asm-generic/resource.h>
> diff --git a/include/uapi/asm-generic/resource.h b/include/uapi/asm-generic/resource.h
> index f12db7a0da64..8a7608a09700 100644
> --- a/include/uapi/asm-generic/resource.h
> +++ b/include/uapi/asm-generic/resource.h
> @@ -58,5 +58,8 @@
>  # define RLIM_INFINITY         (~0UL)
>  #endif
>
> +#ifndef rlimit_as_extra
> +#define rlimit_as_extra() 0
> +#endif
>
>  #endif /* _UAPI_ASM_GENERIC_RESOURCE_H */
> diff --git a/mm/mmap.c b/mm/mmap.c
> index e7d1fcb7ec58..5c07f052bed7 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -3255,7 +3255,13 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
>   */
>  bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages)
>  {
> -       if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT)
> +       unsigned long as_limit = rlimit(RLIMIT_AS);
> +       unsigned long as_limit_plus = as_limit + rlimit_as_extra();
> +
> +       if (as_limit_plus > as_limit)
> +               as_limit = as_limit_plus;
> +

What happens if as_limit_plus overflows?  I guess it's probably okay here.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO
  2018-06-07 14:38 ` [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO Yu-cheng Yu
@ 2018-06-07 20:50   ` Andy Lutomirski
  2018-06-07 22:03     ` H.J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Andy Lutomirski @ 2018-06-07 20:50 UTC (permalink / raw)
  To: Yu-cheng Yu
  Cc: LKML, linux-doc, Linux-MM, linux-arch, X86 ML, H. Peter Anvin,
	Thomas Gleixner, Ingo Molnar, H. J. Lu, Shanbhogue, Vedvyas,
	Ravi V. Shankar, Dave Hansen, Jonathan Corbet, Oleg Nesterov,
	Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
>
> From: "H.J. Lu" <hjl.tools@gmail.com>
>
> When Intel indirect branch tracking is enabled, functions in vDSO which
> may be called indirectly should have endbr32 or endbr64 as the first
> instruction.  We try to compile vDSO with -fcf-protection=branch -mibt
> if possible.  Otherwise, we insert endbr32 or endbr64 by hand to assembly
> codes generated by the compiler.

Wow, that's... a genuine abomination.  Do we really need to support
CET on kernels built with old toolchains?

--Andy

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO
  2018-06-07 20:50   ` Andy Lutomirski
@ 2018-06-07 22:03     ` H.J. Lu
  2018-06-07 23:00       ` Andy Lutomirski
  0 siblings, 1 reply; 16+ messages in thread
From: H.J. Lu @ 2018-06-07 22:03 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Yu-cheng Yu, LKML, linux-doc, Linux-MM, linux-arch, X86 ML,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Shanbhogue,
	Vedvyas, Ravi V. Shankar, Dave Hansen, Jonathan Corbet,
	Oleg Nesterov, Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 1:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
> On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
>>
>> From: "H.J. Lu" <hjl.tools@gmail.com>
>>
>> When Intel indirect branch tracking is enabled, functions in vDSO which
>> may be called indirectly should have endbr32 or endbr64 as the first
>> instruction.  We try to compile vDSO with -fcf-protection=branch -mibt
>> if possible.  Otherwise, we insert endbr32 or endbr64 by hand to assembly
>> codes generated by the compiler.
>
> Wow, that's... a genuine abomination.  Do we really need to support
> CET on kernels built with old toolchains?
>

Yes.  GCC 7 should be able to build CET kernel.


-- 
H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO
  2018-06-07 22:03     ` H.J. Lu
@ 2018-06-07 23:00       ` Andy Lutomirski
  2018-06-08  0:31         ` H.J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Andy Lutomirski @ 2018-06-07 23:00 UTC (permalink / raw)
  To: H. J. Lu
  Cc: Andrew Lutomirski, Yu-cheng Yu, LKML, linux-doc, Linux-MM,
	linux-arch, X86 ML, H. Peter Anvin, Thomas Gleixner, Ingo Molnar,
	Shanbhogue, Vedvyas, Ravi V. Shankar, Dave Hansen,
	Jonathan Corbet, Oleg Nesterov, Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 3:03 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Thu, Jun 7, 2018 at 1:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
> > On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
> >>
> >> From: "H.J. Lu" <hjl.tools@gmail.com>
> >>
> >> When Intel indirect branch tracking is enabled, functions in vDSO which
> >> may be called indirectly should have endbr32 or endbr64 as the first
> >> instruction.  We try to compile vDSO with -fcf-protection=branch -mibt
> >> if possible.  Otherwise, we insert endbr32 or endbr64 by hand to assembly
> >> codes generated by the compiler.
> >
> > Wow, that's... a genuine abomination.  Do we really need to support
> > CET on kernels built with old toolchains?
> >
>
> Yes.  GCC 7 should be able to build CET kernel.
>

Why?  Presumably people running distros that use CET are going to have
kernels build with a CET-supporting compiler.

If we really really need this patch, then I want some kind of
assurance that selftests will catch the failure if something breaks it
or a new vDSO entry point is added.  But my inclination is to NAK this
patch and let the distros carry it if they really really want it.  As
it stands, this sucks for maintainability.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO
  2018-06-07 23:00       ` Andy Lutomirski
@ 2018-06-08  0:31         ` H.J. Lu
  2018-06-08  0:47           ` Andy Lutomirski
  0 siblings, 1 reply; 16+ messages in thread
From: H.J. Lu @ 2018-06-08  0:31 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Yu-cheng Yu, LKML, linux-doc, Linux-MM, linux-arch, X86 ML,
	H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Shanbhogue,
	Vedvyas, Ravi V. Shankar, Dave Hansen, Jonathan Corbet,
	Oleg Nesterov, Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 4:00 PM, Andy Lutomirski <luto@kernel.org> wrote:
> On Thu, Jun 7, 2018 at 3:03 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Thu, Jun 7, 2018 at 1:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
>> > On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
>> >>
>> >> From: "H.J. Lu" <hjl.tools@gmail.com>
>> >>
>> >> When Intel indirect branch tracking is enabled, functions in vDSO which
>> >> may be called indirectly should have endbr32 or endbr64 as the first
>> >> instruction.  We try to compile vDSO with -fcf-protection=branch -mibt
>> >> if possible.  Otherwise, we insert endbr32 or endbr64 by hand to assembly
>> >> codes generated by the compiler.
>> >
>> > Wow, that's... a genuine abomination.  Do we really need to support
>> > CET on kernels built with old toolchains?
>> >
>>
>> Yes.  GCC 7 should be able to build CET kernel.
>>
>
> Why?  Presumably people running distros that use CET are going to have
> kernels build with a CET-supporting compiler.
>

Good point.  It was needed before GCC 8 was released.   We can drop
arch/x86/entry/vdso/endbr.sh now.

-- 
H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO
  2018-06-08  0:31         ` H.J. Lu
@ 2018-06-08  0:47           ` Andy Lutomirski
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Lutomirski @ 2018-06-08  0:47 UTC (permalink / raw)
  To: H. J. Lu
  Cc: Andrew Lutomirski, Yu-cheng Yu, LKML, linux-doc, Linux-MM,
	linux-arch, X86 ML, H. Peter Anvin, Thomas Gleixner, Ingo Molnar,
	Shanbhogue, Vedvyas, Ravi V. Shankar, Dave Hansen,
	Jonathan Corbet, Oleg Nesterov, Arnd Bergmann, mike.kravetz

On Thu, Jun 7, 2018 at 5:31 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Thu, Jun 7, 2018 at 4:00 PM, Andy Lutomirski <luto@kernel.org> wrote:
> > On Thu, Jun 7, 2018 at 3:03 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >>
> >> On Thu, Jun 7, 2018 at 1:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
> >> > On Thu, Jun 7, 2018 at 7:42 AM Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
> >> >>
> >> >> From: "H.J. Lu" <hjl.tools@gmail.com>
> >> >>
> >> >> When Intel indirect branch tracking is enabled, functions in vDSO which
> >> >> may be called indirectly should have endbr32 or endbr64 as the first
> >> >> instruction.  We try to compile vDSO with -fcf-protection=branch -mibt
> >> >> if possible.  Otherwise, we insert endbr32 or endbr64 by hand to assembly
> >> >> codes generated by the compiler.
> >> >
> >> > Wow, that's... a genuine abomination.  Do we really need to support
> >> > CET on kernels built with old toolchains?
> >> >
> >>
> >> Yes.  GCC 7 should be able to build CET kernel.
> >>
> >
> > Why?  Presumably people running distros that use CET are going to have
> > kernels build with a CET-supporting compiler.
> >
>
> Good point.  It was needed before GCC 8 was released.   We can drop
> arch/x86/entry/vdso/endbr.sh now.
>

Phew!  We'll still need a patch to prevent configuring CET on a
compiler that can't support it.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-06-08  0:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-07 14:38 [PATCH 0/7] Control Flow Enforcement - Part (4) Yu-cheng Yu
2018-06-07 14:38 ` [PATCH 1/7] x86/cet: Add Kconfig option for user-mode Indirect Branch Tracking Yu-cheng Yu
2018-06-07 16:43   ` Randy Dunlap
2018-06-07 14:38 ` [PATCH 2/7] x86/cet: User-mode indirect branch tracking support Yu-cheng Yu
2018-06-07 14:38 ` [PATCH 3/7] mm/mmap: Add IBT bitmap size to address space limit check Yu-cheng Yu
2018-06-07 18:39   ` Andy Lutomirski
2018-06-07 14:38 ` [PATCH 4/7] x86/cet: add arcp_prctl functions for indirect branch tracking Yu-cheng Yu
2018-06-07 14:38 ` [PATCH 5/7] x86: Insert endbr32/endbr64 to vDSO Yu-cheng Yu
2018-06-07 20:50   ` Andy Lutomirski
2018-06-07 22:03     ` H.J. Lu
2018-06-07 23:00       ` Andy Lutomirski
2018-06-08  0:31         ` H.J. Lu
2018-06-08  0:47           ` Andy Lutomirski
2018-06-07 14:38 ` [PATCH 6/7] tools: Add cetcmd Yu-cheng Yu
2018-06-07 14:38 ` [PATCH 7/7] x86/cet: Add PTRACE interface for CET Yu-cheng Yu
2018-06-07 18:32   ` Andy Lutomirski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).