diff options
| author | Dave Airlie <airlied@redhat.com> | 2020-08-11 11:58:31 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2020-08-11 11:58:31 +1000 | 
| commit | c44264f9f729fd63bd6a81a6ac5cd6cd49af09e5 (patch) | |
| tree | ad77b18ffeafb50b3eb9ba6472670dc1d96f5558 /arch/x86/kernel/dumpstack.c | |
| parent | ca457ab5908603b36be903e73977afde1ba03c84 (diff) | |
| parent | bcf876870b95592b52519ed4aafcf9d95999bc9c (diff) | |
Merge tag 'v5.8' into drm-next
I need to backmerge 5.8 as I've got a bunch of fixes sitting
on an rc7 base that I want to land.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
| -rw-r--r-- | arch/x86/kernel/dumpstack.c | 27 | 
1 files changed, 17 insertions, 10 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index b037cfa7c0c5..7401cc12c3cc 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -71,6 +71,22 @@ static void printk_stack_address(unsigned long address, int reliable,  	printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);  } +static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src, +		     unsigned int nbytes) +{ +	if (!user_mode(regs)) +		return copy_from_kernel_nofault(buf, (u8 *)src, nbytes); + +	/* +	 * Make sure userspace isn't trying to trick us into dumping kernel +	 * memory by pointing the userspace instruction pointer at it. +	 */ +	if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX)) +		return -EINVAL; + +	return copy_from_user_nmi(buf, (void __user *)src, nbytes); +} +  /*   * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus:   * @@ -97,17 +113,8 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl)  #define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)  	u8 opcodes[OPCODE_BUFSIZE];  	unsigned long prologue = regs->ip - PROLOGUE_SIZE; -	bool bad_ip; - -	/* -	 * Make sure userspace isn't trying to trick us into dumping kernel -	 * memory by pointing the userspace instruction pointer at it. -	 */ -	bad_ip = user_mode(regs) && -		__chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX); -	if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue, -					OPCODE_BUFSIZE)) { +	if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) {  		printk("%sCode: Bad RIP value.\n", loglvl);  	} else {  		printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"  | 
