diff options
| author | Andy Lutomirski <luto@kernel.org> | 2019-04-14 11:59:39 -0400 |
|---|---|---|
| committer | Borislav Petkov <bp@suse.de> | 2019-04-17 06:26:50 -0400 |
| commit | fa33215422fd415a07ec2a00e9f1acdaf0fa8e94 (patch) | |
| tree | 253c63fbef954c557fb8cf6eb445b02410cac5b4 | |
| parent | 7dbcf2b0b770eeb803a416ee8dcbef78e6389d40 (diff) | |
x86/dumpstack: Fix off-by-one errors in stack identification
The get_stack_info() function is off-by-one when checking whether an
address is on a IRQ stack or a IST stack. This prevents an overflowed
IRQ or IST stack from being dumped properly.
[ tglx: Do the same for 32-bit ]
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Sean Christopherson <sean.j.christopherson@intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190414160143.785651055@linutronix.de
| -rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 4 |
2 files changed, 4 insertions, 4 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index cd53f3030e40..d305440ebe9c 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
| @@ -41,7 +41,7 @@ static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) | |||
| 41 | * This is a software stack, so 'end' can be a valid stack pointer. | 41 | * This is a software stack, so 'end' can be a valid stack pointer. |
| 42 | * It just means the stack is empty. | 42 | * It just means the stack is empty. |
| 43 | */ | 43 | */ |
| 44 | if (stack <= begin || stack > end) | 44 | if (stack < begin || stack > end) |
| 45 | return false; | 45 | return false; |
| 46 | 46 | ||
| 47 | info->type = STACK_TYPE_IRQ; | 47 | info->type = STACK_TYPE_IRQ; |
| @@ -66,7 +66,7 @@ static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) | |||
| 66 | * This is a software stack, so 'end' can be a valid stack pointer. | 66 | * This is a software stack, so 'end' can be a valid stack pointer. |
| 67 | * It just means the stack is empty. | 67 | * It just means the stack is empty. |
| 68 | */ | 68 | */ |
| 69 | if (stack <= begin || stack > end) | 69 | if (stack < begin || stack > end) |
| 70 | return false; | 70 | return false; |
| 71 | 71 | ||
| 72 | info->type = STACK_TYPE_SOFTIRQ; | 72 | info->type = STACK_TYPE_SOFTIRQ; |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 5cdb9e84da57..90f0fa88cbb3 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
| @@ -65,7 +65,7 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info) | |||
| 65 | begin = end - (exception_stack_sizes[k] / sizeof(long)); | 65 | begin = end - (exception_stack_sizes[k] / sizeof(long)); |
| 66 | regs = (struct pt_regs *)end - 1; | 66 | regs = (struct pt_regs *)end - 1; |
| 67 | 67 | ||
| 68 | if (stack <= begin || stack >= end) | 68 | if (stack < begin || stack >= end) |
| 69 | continue; | 69 | continue; |
| 70 | 70 | ||
| 71 | info->type = STACK_TYPE_EXCEPTION + k; | 71 | info->type = STACK_TYPE_EXCEPTION + k; |
| @@ -88,7 +88,7 @@ static bool in_irq_stack(unsigned long *stack, struct stack_info *info) | |||
| 88 | * This is a software stack, so 'end' can be a valid stack pointer. | 88 | * This is a software stack, so 'end' can be a valid stack pointer. |
| 89 | * It just means the stack is empty. | 89 | * It just means the stack is empty. |
| 90 | */ | 90 | */ |
| 91 | if (stack <= begin || stack > end) | 91 | if (stack < begin || stack >= end) |
| 92 | return false; | 92 | return false; |
| 93 | 93 | ||
| 94 | info->type = STACK_TYPE_IRQ; | 94 | info->type = STACK_TYPE_IRQ; |
