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 <cmetc...@mellanox.com>
---
 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 ++
 4 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 03663740c866..62e1e34cffc5 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>
@@ -95,6 +96,13 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs 
*regs, u32 arch)
        }
 #endif
 
+       /* 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
@@ -220,7 +228,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)
 {
@@ -254,11 +262,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 c7b551028740..5280b92bdc3b 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 ade185a46b1d..bc50c275bb9b 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>
@@ -398,6 +399,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 e830c71a1323..86def02ff9a0 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/traps.h>                 /* dotraplinkage, ...           */
 #include <asm/pgalloc.h>               /* pgd_*(), ...                 */
@@ -1155,6 +1156,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

Reply via email to