lkml.org 
[lkml]   [2020]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC][PATCH 15/24] x86/pti: Execute syscall functions on the kernel stack
    Date
    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
    \
     
     \ /
      Last update: 2020-11-09 15:49    [W:4.128 / U:0.332 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site