Patch "x86/unwinder: Handle stack overflows more gracefully" has been added to the 4.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
x86/unwinder: Handle stack overflows more gracefully
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-unwinder-handle-stack-overflows-more-gracefully.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
b02fcf9ba1211097754b286043cd87a8b4907e75Mon Sep 17 00:00:00 2001
From: Josh Poimboeuf <[email protected]>
Date: Mon, 4 Dec 2017 15:07:09 +0100
Subject: x86/unwinder: Handle stack overflows more gracefully
From: Josh Poimboeuf <[email protected]>
commit b02fcf9ba1211097754b286043cd87a8b4907e75 upstream.
There are at least two unwinder bugs hindering the debugging of stack-overflow crashes:
- It doesn't deal gracefully with the case where the stack overflows and the stack pointer itself isn't on a valid stack but the to-be-dereferenced data *is*.
- The ORC oops dump code doesn't know how to print partial pt_regs, for the case where if we get an interrupt/exception in *early* entry code before the full pt_regs have been saved.
Fix both issues.
http://lkml.kernel.org/r/20171126024031.uxi4numpbjm5rlbr@treble
--- arch/x86/include/asm/kdebug.h | 1 arch/x86/include/asm/unwind.h | 7 +++ arch/x86/kernel/dumpstack.c | 32 ++++++++++++++--- arch/x86/kernel/process_64.c | 11 ++---- arch/x86/kernel/unwind_orc.c | 76 ++++++++++++++---------------------------- 5 files changed, 66 insertions(+), 61 deletions(-)
arch/x86/include/asm/kdebug.h +1 -0
@@ -26,6 +26,7 @@ extern void die(const char *, struct pt_extern int __must_check __die (const char *,struct pt_regs *,long );extern void show_stack_regs (struct pt_regs *regs);extern void __show_regs (struct pt_regs *regs,int all); +extern void show_iret_regs (struct pt_regs *regs);extern unsigned long oops_begin (void );extern void oops_end (unsigned long ,struct pt_regs *,int signr);
arch/x86/include/asm/unwind.h +7 -0
@@ -7,6 +7,9 @@#include <asm/ptrace.h> #include <asm/stacktrace.h> +#define IRET_FRAME_OFFSET (offsetof(struct pt_regs, ip)) +#define IRET_FRAME_SIZE (sizeof(struct pt_regs) - IRET_FRAME_OFFSET) +struct unwind_state {struct stack_info stack_info;unsigned long stack_mask;
@@ -52,6 +55,10 @@ void unwind_start(struct unwind_state *s }#if defined(CONFIG_UNWINDER_ORC ) || defined(CONFIG_UNWINDER_FRAME_POINTER ) +/* +* WARNING: The entire pt_regs may not be safe to dereference. In some cases, +* only the iret frame registers are accessible. Use with caution! +*/ static inline struct pt_regs *unwind_get_entry_regs (struct unwind_state *state) {if (unwind_done (state))
arch/x86/kernel/dumpstack.c +27 -5
@@ -50,6 +50,28 @@ static void printk_stack_address(unsigneprintk ("%s %s%pB\n" , log_lvl, reliable ?"" :"? " , (void *)address); } +void show_iret_regs (struct pt_regs *regs) +{ +printk (KERN_DEFAULT "RIP: %04x:%pS\n" , (int )regs->cs, (void *)regs->ip); +printk (KERN_DEFAULT "RSP: %04x:%016lx EFLAGS: %08lx" , (int )regs->ss, + regs->sp, regs->flags); +} + +static void show_regs_safe (struct stack_info *info,struct pt_regs *regs) +{ +if (on_stack (info, regs,sizeof (*regs))) +__show_regs (regs,0 ); +else if (on_stack (info, (void *)regs +IRET_FRAME_OFFSET , +IRET_FRAME_SIZE )) { +/* +* When an interrupt or exception occurs in entry code, the +* full pt_regs might not have been saved yet. In that case +* just print the iret frame. +*/ +show_iret_regs (regs); + } +} +void show_trace_log_lvl (struct task_struct *task,struct pt_regs *regs,unsigned long *stack,char *log_lvl) {
@@ -94,8 +116,8 @@ void show_trace_log_lvl(struct task_struif (stack_name)printk ("%s <%s>\n" , log_lvl, stack_name); -if (regs &&on_stack (&stack_info, regs,sizeof (*regs))) -__show_regs (regs,0 ); +if (regs) +show_regs_safe (&stack_info, regs);/* * Scan the stack, printing any text addresses we find. At the
@@ -119,7 +141,7 @@ void show_trace_log_lvl(struct task_stru/* * Don't print regs->ip again if it was already printed -* by __show_regs() below. +* by show_regs_safe() below. */ if (regs && stack == ®s->ip) goto next;
@@ -155,8 +177,8 @@ next:/* if the frame has entry regs, print them */ regs =unwind_get_entry_regs (&state); -if (regs &&on_stack (&stack_info, regs,sizeof (*regs))) -__show_regs (regs,0 ); +if (regs) +show_regs_safe (&stack_info, regs); }if (stack_name)
arch/x86/kernel/process_64.c +5 -6
@@ -69,9 +69,8 @@ void __show_regs(struct pt_regs *regs, iunsigned int fsindex, gsindex;unsigned int ds, cs, es; -printk (KERN_DEFAULT "RIP: %04lx:%pS\n" , regs->cs, (void *)regs->ip); -printk (KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx" , regs->ss, - regs->sp, regs->flags); +show_iret_regs (regs); +if (regs->orig_ax !=-1 )pr_cont (" ORIG_RAX: %016lx\n" , regs->orig_ax);else
@@ -88,6 +87,9 @@ void __show_regs(struct pt_regs *regs, iprintk (KERN_DEFAULT "R13: %016lx R14: %016lx R15: %016lx\n" , regs->r13, regs->r14, regs->r15); +if (!all) +return ; + asm("movl %%ds,%0" :"=r" (ds)); asm("movl %%cs,%0" :"=r" (cs)); asm("movl %%es,%0" :"=r" (es));
@@ -98,9 +100,6 @@ void __show_regs(struct pt_regs *regs, irdmsrl (MSR_GS_BASE , gs);rdmsrl (MSR_KERNEL_GS_BASE , shadowgs); -if (!all) -return ; - cr0 =read_cr0 (); cr2 =read_cr2 (); cr3 =__read_cr3 ();
arch/x86/kernel/unwind_orc.c +26 -50
124 lines not on this page · raw message
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/x86-cpufeatures-fix-various-details-in-the-feature-definitions.patch queue-4.14/x86-entry-64-move-the-ist-stacks-into-struct-cpu_entry_area.patch queue-4.14/x86-dumpstack-add-get_stack_info-support-for-the-sysenter-stack.patch queue-4.14/x86-asm-don-t-use-the-confusing-.ifeq-directive.patch queue-4.14/x86-entry-remap-the-tss-into-the-cpu-entry-area.patch queue-4.14/x86-entry-64-paravirt-use-paravirt-safe-macro-to-access-eflags.patch queue-4.14/x86-mm-fixmap-generalize-the-gdt-fixmap-mechanism-introduce-struct-cpu_entry_area.patch queue-4.14/x86-paravirt-dont-patch-flush_tlb_single.patch queue-4.14/x86-dumpstack-handle-stack-overflow-on-all-stacks.patch queue-4.14/x86-entry-64-return-to-userspace-from-the-trampoline-stack.patch queue-4.14/x86-paravirt-provide-a-way-to-check-for-hypervisors.patch queue-4.14/x86-entry-64-create-a-per-cpu-syscall-entry-trampoline.patch queue-4.14/x86-boot-relocate-definition-of-the-initial-state-of-cr0.patch queue-4.14/objtool-don-t-report-end-of-section-error-after-an-empty-unwind-hint.patch queue-4.14/x86-entry-64-use-a-per-cpu-trampoline-stack-for-idt-entries.patch queue-4.14/x86-cpufeature-add-user-mode-instruction-prevention-definitions.patch queue-4.14/x86-cpufeatures-make-cpu-bugs-sticky.patch queue-4.14/x86-espfix-64-stop-assuming-that-pt_regs-is-on-the-entry-stack.patch queue-4.14/x86-xen-fix-xen-head-elf-annotations.patch queue-4.14/x86-entry-move-sysenter_stack-to-the-beginning-of-struct-tss_struct.patch queue-4.14/x86-entry-64-allocate-and-enable-the-sysenter-stack.patch queue-4.14/x86-unwinder-orc-dont-bail-on-stack-overflow.patch queue-4.14/x86-head-fix-head-elf-function-annotations.patch queue-4.14/objtool-print-top-level-commands-on-incorrect-usage.patch queue-4.14/x86-unwind-rename-unwinder-config-options-to-config_unwinder_.patch queue-4.14/x86-head-add-unwind-hint-annotations.patch queue-4.14/x86-head-remove-unused-bad_address-code.patch queue-4.14/x86-xen-add-unwind-hint-annotations.patch queue-4.14/x86-kasan-64-teach-kasan-about-the-cpu_entry_area.patch queue-4.14/x86-head-remove-confusing-comment.patch queue-4.14/x86-entry-64-remove-the-sysenter-stack-canary.patch queue-4.14/x86-unwinder-make-config_unwinder_orc-y-the-default-in-the-64-bit-defconfig.patch queue-4.14/x86-entry-gdt-put-per-cpu-gdt-remaps-in-ascending-order.patch queue-4.14/x86-entry-fix-assumptions-that-the-hw-tss-is-at-the-beginning-of-cpu_tss.patch queue-4.14/x86-cpufeatures-re-tabulate-the-x86_feature-definitions.patch queue-4.14/x86-entry-64-make-cpu_entry_area.tss-read-only.patch queue-4.14/x86-unwind-make-config_unwinder_orc-y-the-default-in-kconfig-for-64-bit.patch queue-4.14/x86-mm-relocate-page-fault-error-codes-to-traps.h.patch queue-4.14/x86-unwinder-handle-stack-overflows-more-gracefully.patch queue-4.14/x86-irq-64-print-the-offending-ip-in-the-stack-overflow-warning.patch queue-4.14/x86-entry-clean-up-the-sysenter_stack-code.patch queue-4.14/x86-entry-64-separate-cpu_current_top_of_stack-from-tss.sp0.patch queue-4.14/x86-boot-annotate-verify_cpu-as-a-callable-function.patch queue-4.14/x86-irq-remove-an-old-outdated-comment-about-context-tracking-races.patch