Messages in this thread Patch in this message | | | From | Chris Metcalf <> | Subject | [PATCH v12 10/13] arch/x86: enable task isolation functionality | Date | Tue, 5 Apr 2016 13:38:39 -0400 |
| |
In prepare_exit_to_usermode(), call task_isolation_ready() for TIF_TASK_ISOLATION tasks when we are checking the thread-info flags, and after we've handled the other work, call task_isolation_enter() for such tasks.
In syscall_trace_enter_phase1(), we add the necessary support for strict-mode detection of syscalls.
We add strict reporting for the kernel exception types that do not result in signals, namely non-signalling page faults and non-signalling MPX fixups.
Signed-off-by: Chris Metcalf <cmetcalf@mellanox.com> --- arch/x86/Kconfig | 1 + arch/x86/entry/common.c | 18 +++++++++++++++++- arch/x86/include/asm/thread_info.h | 2 ++ arch/x86/kernel/traps.c | 2 ++ arch/x86/mm/fault.c | 2 ++ 5 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2dc18605831f..760401ba3df0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -89,6 +89,7 @@ config X86 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SOFT_DIRTY if X86_64 + select HAVE_ARCH_TASK_ISOLATION select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_BPF_JIT if X86_64 diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index e79d93d44ecd..31dfe4ff8915 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -21,6 +21,7 @@ #include <linux/context_tracking.h> #include <linux/user-return-notifier.h> #include <linux/uprobes.h> +#include <linux/isolation.h> #include <asm/desc.h> #include <asm/traps.h> @@ -87,6 +88,13 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch) work = ACCESS_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY; + /* In isolation mode, we may prevent the syscall from running. */ + if (work & _TIF_TASK_ISOLATION) { + if (task_isolation_syscall(regs->orig_ax) == -1) + return -1; + work &= ~_TIF_TASK_ISOLATION; + } + #ifdef CONFIG_SECCOMP /* * Do seccomp first -- it should minimize exposure of other @@ -202,7 +210,7 @@ long syscall_trace_enter(struct pt_regs *regs) #define EXIT_TO_USERMODE_LOOP_FLAGS \ (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ - _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY) + _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY | _TIF_TASK_ISOLATION) static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) { @@ -236,11 +244,19 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) if (cached_flags & _TIF_USER_RETURN_NOTIFY) fire_user_return_notifiers(); + if (cached_flags & _TIF_TASK_ISOLATION) + task_isolation_enter(); + /* Disable IRQs and retry */ local_irq_disable(); cached_flags = READ_ONCE(pt_regs_to_thread_info(regs)->flags); + /* Clear task isolation from cached_flags manually. */ + if ((cached_flags & _TIF_TASK_ISOLATION) && + task_isolation_ready()) + cached_flags &= ~_TIF_TASK_ISOLATION; + if (!(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS)) break; diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 82866697fcf1..057176ae597f 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -97,6 +97,7 @@ struct thread_info { #define TIF_SECCOMP 8 /* secure computing */ #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ #define TIF_UPROBE 12 /* breakpointed or singlestepping */ +#define TIF_TASK_ISOLATION 13 /* task isolation enabled for task */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ #define TIF_IA32 17 /* IA32 compatibility process */ #define TIF_FORK 18 /* ret_from_fork */ @@ -121,6 +122,7 @@ struct thread_info { #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) #define _TIF_UPROBE (1 << TIF_UPROBE) +#define _TIF_TASK_ISOLATION (1 << TIF_TASK_ISOLATION) #define _TIF_NOTSC (1 << TIF_NOTSC) #define _TIF_IA32 (1 << TIF_IA32) #define _TIF_FORK (1 << TIF_FORK) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 06cbe25861f1..b02205085571 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -36,6 +36,7 @@ #include <linux/mm.h> #include <linux/smp.h> #include <linux/io.h> +#include <linux/isolation.h> #ifdef CONFIG_EISA #include <linux/ioport.h> @@ -382,6 +383,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) case 2: /* Bound directory has invalid entry. */ if (mpx_handle_bd_fault()) goto exit_trap; + task_isolation_exception("bounds check"); break; /* Success, it was handled */ case 1: /* Bound violation. */ info = mpx_generate_siginfo(regs); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 5ce1ed02f7e8..025e9d2850c1 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -14,6 +14,7 @@ #include <linux/prefetch.h> /* prefetchw */ #include <linux/context_tracking.h> /* exception_enter(), ... */ #include <linux/uaccess.h> /* faulthandler_disabled() */ +#include <linux/isolation.h> /* task_isolation_exception */ #include <asm/cpufeature.h> /* boot_cpu_has, ... */ #include <asm/traps.h> /* dotraplinkage, ... */ @@ -1259,6 +1260,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, local_irq_enable(); error_code |= PF_USER; flags |= FAULT_FLAG_USER; + task_isolation_exception("page fault at %#lx", address); } else { if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); -- 2.7.2
| |