From: Greg Kroah-Hartman Date: Mon, 3 Sep 2018 16:27:02 +0000 (+0200) Subject: 4.18-stable patches X-Git-Tag: v3.18.121~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e7b218d2f2e00812854c8746992339afbdf50038;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: x86-dumpstack-don-t-dump-kernel-memory-based-on-usermode-rip.patch --- diff --git a/queue-4.18/series b/queue-4.18/series index 6bdd58a13f8..f45c3d8d7f4 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -119,4 +119,5 @@ power-generic-adc-battery-fix-out-of-bounds-write-when-copying-channel-propertie power-generic-adc-battery-check-for-duplicate-properties-copied-from-iio-channels.patch watchdog-mark-watchdog-touch-functions-as-notrace.patch cdrom-fix-info-leak-oob-read-in-cdrom_ioctl_drive_status.patch +x86-dumpstack-don-t-dump-kernel-memory-based-on-usermode-rip.patch x86-kvm-avoid-unused-variable-warning.patch diff --git a/queue-4.18/x86-dumpstack-don-t-dump-kernel-memory-based-on-usermode-rip.patch b/queue-4.18/x86-dumpstack-don-t-dump-kernel-memory-based-on-usermode-rip.patch new file mode 100644 index 00000000000..bd0f41d3c59 --- /dev/null +++ b/queue-4.18/x86-dumpstack-don-t-dump-kernel-memory-based-on-usermode-rip.patch @@ -0,0 +1,104 @@ +From 342db04ae71273322f0011384a9ed414df8bdae4 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Tue, 28 Aug 2018 17:49:01 +0200 +Subject: x86/dumpstack: Don't dump kernel memory based on usermode RIP + +From: Jann Horn + +commit 342db04ae71273322f0011384a9ed414df8bdae4 upstream. + +show_opcodes() is used both for dumping kernel instructions and for dumping +user instructions. If userspace causes #PF by jumping to a kernel address, +show_opcodes() can be reached with regs->ip controlled by the user, +pointing to kernel code. Make sure that userspace can't trick us into +dumping kernel memory into dmesg. + +Fixes: 7cccf0725cf7 ("x86/dumpstack: Add a show_ip() function") +Signed-off-by: Jann Horn +Signed-off-by: Thomas Gleixner +Reviewed-by: Kees Cook +Reviewed-by: Borislav Petkov +Cc: "H. Peter Anvin" +Cc: Andy Lutomirski +Cc: security@kernel.org +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180828154901.112726-1-jannh@google.com +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/x86/include/asm/stacktrace.h | 2 +- + arch/x86/kernel/dumpstack.c | 21 +++++++++++++++------ + arch/x86/mm/fault.c | 2 +- + 3 files changed, 17 insertions(+), 8 deletions(-) + +--- a/arch/x86/include/asm/stacktrace.h ++++ b/arch/x86/include/asm/stacktrace.h +@@ -111,6 +111,6 @@ static inline unsigned long caller_frame + return (unsigned long)frame; + } + +-void show_opcodes(u8 *rip, const char *loglvl); ++void show_opcodes(struct pt_regs *regs, const char *loglvl); + void show_ip(struct pt_regs *regs, const char *loglvl); + #endif /* _ASM_X86_STACKTRACE_H */ +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -92,23 +92,32 @@ static void printk_stack_address(unsigne + * Thus, the 2/3rds prologue and 64 byte OPCODE_BUFSIZE is just a random + * guesstimate in attempt to achieve all of the above. + */ +-void show_opcodes(u8 *rip, const char *loglvl) ++void show_opcodes(struct pt_regs *regs, const char *loglvl) + { + unsigned int code_prologue = OPCODE_BUFSIZE * 2 / 3; + u8 opcodes[OPCODE_BUFSIZE]; +- u8 *ip; ++ unsigned long ip; + int i; ++ bool bad_ip; + + printk("%sCode: ", loglvl); + +- ip = (u8 *)rip - code_prologue; +- if (probe_kernel_read(opcodes, ip, OPCODE_BUFSIZE)) { ++ ip = regs->ip - code_prologue; ++ ++ /* ++ * 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(ip, OPCODE_BUFSIZE, TASK_SIZE_MAX); ++ ++ if (bad_ip || probe_kernel_read(opcodes, (u8 *)ip, OPCODE_BUFSIZE)) { + pr_cont("Bad RIP value.\n"); + return; + } + + for (i = 0; i < OPCODE_BUFSIZE; i++, ip++) { +- if (ip == rip) ++ if (ip == regs->ip) + pr_cont("<%02x> ", opcodes[i]); + else + pr_cont("%02x ", opcodes[i]); +@@ -123,7 +132,7 @@ void show_ip(struct pt_regs *regs, const + #else + printk("%sRIP: %04x:%pS\n", loglvl, (int)regs->cs, (void *)regs->ip); + #endif +- show_opcodes((u8 *)regs->ip, loglvl); ++ show_opcodes(regs, loglvl); + } + + void show_iret_regs(struct pt_regs *regs) +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -838,7 +838,7 @@ show_signal_msg(struct pt_regs *regs, un + + printk(KERN_CONT "\n"); + +- show_opcodes((u8 *)regs->ip, loglvl); ++ show_opcodes(regs, loglvl); + } + + static void