lkml.org 
[lkml]   [2019]   [Nov]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 040/151] kprobes, x86/ptrace.h: Make regs_get_kernel_stack_nth() not fault on bad stack
    Date
    From: Steven Rostedt (VMware) <rostedt@goodmis.org>

    [ Upstream commit c2712b858187f5bcd7b042fe4daa3ba3a12635c0 ]

    Andy had some concerns about using regs_get_kernel_stack_nth() in a new
    function regs_get_kernel_argument() as if there's any error in the stack
    code, it could cause a bad memory access. To be on the safe side, call
    probe_kernel_read() on the stack address to be extra careful in accessing
    the memory. A helper function, regs_get_kernel_stack_nth_addr(), was added
    to just return the stack address (or NULL if not on the stack), that will be
    used to find the address (and could be used by other functions) and read the
    address with kernel_probe_read().

    Requested-by: Andy Lutomirski <luto@amacapital.net>
    Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
    Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Josh Poimboeuf <jpoimboe@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/20181017165951.09119177@gandalf.local.home
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/x86/include/asm/ptrace.h | 42 +++++++++++++++++++++++++++++------
    1 file changed, 35 insertions(+), 7 deletions(-)

    diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
    index ea78a8438a8af..fb489cd848faa 100644
    --- a/arch/x86/include/asm/ptrace.h
    +++ b/arch/x86/include/asm/ptrace.h
    @@ -199,24 +199,52 @@ static inline int regs_within_kernel_stack(struct pt_regs *regs,
    (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
    }

    +/**
    + * regs_get_kernel_stack_nth_addr() - get the address of the Nth entry on stack
    + * @regs: pt_regs which contains kernel stack pointer.
    + * @n: stack entry number.
    + *
    + * regs_get_kernel_stack_nth() returns the address of the @n th entry of the
    + * kernel stack which is specified by @regs. If the @n th entry is NOT in
    + * the kernel stack, this returns NULL.
    + */
    +static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs, unsigned int n)
    +{
    + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
    +
    + addr += n;
    + if (regs_within_kernel_stack(regs, (unsigned long)addr))
    + return addr;
    + else
    + return NULL;
    +}
    +
    +/* To avoid include hell, we can't include uaccess.h */
    +extern long probe_kernel_read(void *dst, const void *src, size_t size);
    +
    /**
    * regs_get_kernel_stack_nth() - get Nth entry of the stack
    * @regs: pt_regs which contains kernel stack pointer.
    * @n: stack entry number.
    *
    * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
    - * is specified by @regs. If the @n th entry is NOT in the kernel stack,
    + * is specified by @regs. If the @n th entry is NOT in the kernel stack
    * this returns 0.
    */
    static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
    unsigned int n)
    {
    - unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
    - addr += n;
    - if (regs_within_kernel_stack(regs, (unsigned long)addr))
    - return *addr;
    - else
    - return 0;
    + unsigned long *addr;
    + unsigned long val;
    + long ret;
    +
    + addr = regs_get_kernel_stack_nth_addr(regs, n);
    + if (addr) {
    + ret = probe_kernel_read(&val, addr, sizeof(val));
    + if (!ret)
    + return val;
    + }
    + return 0;
    }

    #define arch_has_single_step() (1)
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-11-27 21:42    [W:6.497 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site