Messages in this thread Patch in this message | | | From | Alexandre Chartre <> | Subject | [RFC][PATCH 15/24] x86/pti: Execute syscall functions on the kernel stack | Date | Mon, 9 Nov 2020 12:23:10 +0100 |
| |
During a syscall, the kernel is entered and it switches the stack to the PTI stack which is mapped both in the kernel and in the user page-table. When executing the syscall function, switch to the kernel stack (which is mapped only in the kernel page-table) so that no kernel data leak to the userland through the stack.
Signed-off-by: Alexandre Chartre <alexandre.chartre@oracle.com> --- arch/x86/entry/common.c | 11 ++++++++++- arch/x86/entry/entry_64.S | 1 + arch/x86/include/asm/irq_stack.h | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 54d0931801e1..ead6a4c72e6a 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -56,10 +56,19 @@ __visible noinstr void return_from_fork(struct pt_regs *regs, static __always_inline void run_syscall(sys_call_ptr_t sysfunc, struct pt_regs *regs) { + unsigned long stack; + if (!sysfunc) return; - regs->ax = sysfunc(regs); + if (!pti_enabled()) { + regs->ax = sysfunc(regs); + return; + } + + stack = (unsigned long)task_top_of_kernel_stack(current); + regs->ax = asm_call_syscall_on_stack((void *)(stack - 8), + sysfunc, regs); } #ifdef CONFIG_X86_64 diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 29beab46bedd..6b88a0eb8975 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -771,6 +771,7 @@ SYM_FUNC_START(asm_call_on_stack_2) SYM_FUNC_START(asm_call_on_stack_3) SYM_INNER_LABEL(asm_call_sysvec_on_stack, SYM_L_GLOBAL) SYM_INNER_LABEL(asm_call_irq_on_stack, SYM_L_GLOBAL) +SYM_INNER_LABEL(asm_call_syscall_on_stack, SYM_L_GLOBAL) /* * Save the frame pointer unconditionally. This allows the ORC * unwinder to handle the stack switch. diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h index 359427216336..108d9da7c01c 100644 --- a/arch/x86/include/asm/irq_stack.h +++ b/arch/x86/include/asm/irq_stack.h @@ -5,6 +5,7 @@ #include <linux/ptrace.h> #include <asm/processor.h> +#include <asm/syscall.h> #ifdef CONFIG_X86_64 static __always_inline bool irqstack_active(void) @@ -25,6 +26,8 @@ void asm_call_sysvec_on_stack(void *sp, void (*func)(struct pt_regs *regs), struct pt_regs *regs); void asm_call_irq_on_stack(void *sp, void (*func)(struct irq_desc *desc), struct irq_desc *desc); +long asm_call_syscall_on_stack(void *sp, sys_call_ptr_t func, + struct pt_regs *regs); static __always_inline void __run_on_irqstack(void (*func)(void)) { -- 2.18.4
| |