If a system call runs in isolated context, it's accesses to kernel code and data will be verified by SCI susbsytem. Signed-off-by: Mike Rapoport <rppt@xxxxxxxxxxxxx> --- arch/x86/mm/fault.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 9d5c75f..baa2a2f 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -18,6 +18,7 @@ #include <linux/uaccess.h> /* faulthandler_disabled() */ #include <linux/efi.h> /* efi_recover_from_page_fault()*/ #include <linux/mm_types.h> +#include <linux/sci.h> /* sci_verify_and_map() */ #include <asm/cpufeature.h> /* boot_cpu_has, ... */ #include <asm/traps.h> /* dotraplinkage, ... */ @@ -1254,6 +1255,30 @@ static int fault_in_kernel_space(unsigned long address) return address >= TASK_SIZE_MAX; } +#ifdef CONFIG_SYSCALL_ISOLATION +static int sci_fault(struct pt_regs *regs, unsigned long hw_error_code, + unsigned long address) +{ + struct task_struct *tsk = current; + + if (!tsk->in_isolated_syscall) + return 0; + + if (!sci_verify_and_map(regs, address, hw_error_code)) { + this_cpu_write(cpu_sci.sci_syscall, 0); + no_context(regs, hw_error_code, address, SIGKILL, 0); + } + + return 1; +} +#else +static inline int sci_fault(struct pt_regs *regs, unsigned long hw_error_code, + unsigned long address) +{ + return 0; +} +#endif + /* * Called for all faults where 'address' is part of the kernel address * space. Might get called for faults that originate from *code* that @@ -1301,6 +1326,9 @@ do_kern_addr_fault(struct pt_regs *regs, unsigned long hw_error_code, if (kprobes_fault(regs)) return; + if (sci_fault(regs, hw_error_code, address)) + return; + /* * Note, despite being a "bad area", there are quite a few * acceptable reasons to get here, such as erratum fixups -- 2.7.4