summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2018-10-17 16:59:51 -0400
committerIngo Molnar <mingo@kernel.org>2018-10-18 02:28:35 -0400
commitc2712b858187f5bcd7b042fe4daa3ba3a12635c0 (patch)
treecbf147c76c6aadc067dc813aaa652ca4cb42e2ae
parentd4ae552982de39417d17f823df1f06b1cbc3686c (diff)
kprobes, x86/ptrace.h: Make regs_get_kernel_stack_nth() not fault on bad stack
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>
-rw-r--r--arch/x86/include/asm/ptrace.h42
1 files changed, 35 insertions, 7 deletions
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 6de1fd3d0097..ee696efec99f 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -237,23 +237,51 @@ static inline int regs_within_kernel_stack(struct pt_regs *regs,
237} 237}
238 238
239/** 239/**
240 * regs_get_kernel_stack_nth_addr() - get the address of the Nth entry on stack
241 * @regs: pt_regs which contains kernel stack pointer.
242 * @n: stack entry number.
243 *
244 * regs_get_kernel_stack_nth() returns the address of the @n th entry of the
245 * kernel stack which is specified by @regs. If the @n th entry is NOT in
246 * the kernel stack, this returns NULL.
247 */
248static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs, unsigned int n)
249{
250 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
251
252 addr += n;
253 if (regs_within_kernel_stack(regs, (unsigned long)addr))
254 return addr;
255 else
256 return NULL;
257}
258
259/* To avoid include hell, we can't include uaccess.h */
260extern long probe_kernel_read(void *dst, const void *src, size_t size);
261
262/**
240 * regs_get_kernel_stack_nth() - get Nth entry of the stack 263 * regs_get_kernel_stack_nth() - get Nth entry of the stack
241 * @regs: pt_regs which contains kernel stack pointer. 264 * @regs: pt_regs which contains kernel stack pointer.
242 * @n: stack entry number. 265 * @n: stack entry number.
243 * 266 *
244 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which 267 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
245 * is specified by @regs. If the @n th entry is NOT in the kernel stack, 268 * is specified by @regs. If the @n th entry is NOT in the kernel stack
246 * this returns 0. 269 * this returns 0.
247 */ 270 */
248static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, 271static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
249 unsigned int n) 272 unsigned int n)
250{ 273{
251 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); 274 unsigned long *addr;
252 addr += n; 275 unsigned long val;
253 if (regs_within_kernel_stack(regs, (unsigned long)addr)) 276 long ret;
254 return *addr; 277
255 else 278 addr = regs_get_kernel_stack_nth_addr(regs, n);
256 return 0; 279 if (addr) {
280 ret = probe_kernel_read(&val, addr, sizeof(val));
281 if (!ret)
282 return val;
283 }
284 return 0;
257} 285}
258 286
259#define arch_has_single_step() (1) 287#define arch_has_single_step() (1)