From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933584AbcIOKme (ORCPT ); Thu, 15 Sep 2016 06:42:34 -0400 Received: from terminus.zytor.com ([198.137.202.10]:38432 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754934AbcIOKm3 (ORCPT ); Thu, 15 Sep 2016 06:42:29 -0400 Date: Thu, 15 Sep 2016 03:41:25 -0700 From: tip-bot for Josh Poimboeuf Message-ID: Cc: keescook@chromium.org, nilayvaish@gmail.com, bp@alien8.de, luto@kernel.org, brgerst@gmail.com, fweisbec@gmail.com, byungchul.park@lge.com, linux-kernel@vger.kernel.org, jpoimboe@redhat.com, tglx@linutronix.de, rostedt@goodmis.org, mingo@kernel.org, torvalds@linux-foundation.org, hpa@zytor.com, peterz@infradead.org, luto@amacapital.net, dvlasenk@redhat.com Reply-To: linux-kernel@vger.kernel.org, byungchul.park@lge.com, luto@kernel.org, bp@alien8.de, fweisbec@gmail.com, brgerst@gmail.com, keescook@chromium.org, nilayvaish@gmail.com, dvlasenk@redhat.com, luto@amacapital.net, peterz@infradead.org, torvalds@linux-foundation.org, hpa@zytor.com, mingo@kernel.org, tglx@linutronix.de, jpoimboe@redhat.com, rostedt@goodmis.org In-Reply-To: <95de5db4cfe111754845a5cef04e20630d01423f.1473905218.git.jpoimboe@redhat.com> References: <95de5db4cfe111754845a5cef04e20630d01423f.1473905218.git.jpoimboe@redhat.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/asm] x86/dumpstack: Add recursion checking for all stacks Git-Commit-ID: fcd709ef20a9d83bdb7524d27cd6719dac8690a0 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: fcd709ef20a9d83bdb7524d27cd6719dac8690a0 Gitweb: http://git.kernel.org/tip/fcd709ef20a9d83bdb7524d27cd6719dac8690a0 Author: Josh Poimboeuf AuthorDate: Wed, 14 Sep 2016 21:07:44 -0500 Committer: Ingo Molnar CommitDate: Thu, 15 Sep 2016 08:13:15 +0200 x86/dumpstack: Add recursion checking for all stacks in_exception_stack() has some recursion checking which makes sure the stack trace code never traverses a given exception stack more than once. This prevents an infinite loop if corruption somehow causes a stack's "next stack" pointer to point to itself (directly or indirectly). The recursion checking can be useful for other stacks in addition to the exception stack, so extend it to work for all stacks. Signed-off-by: Josh Poimboeuf Cc: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Byungchul Park Cc: Denys Vlasenko Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Nilay Vaish Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/95de5db4cfe111754845a5cef04e20630d01423f.1473905218.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/dumpstack_32.c | 22 +++++++++++++++++++--- arch/x86/kernel/dumpstack_64.c | 35 +++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 50076d4..2d65cfa 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -89,16 +89,32 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, task = task ? : current; if (in_task_stack(stack, task, info)) - return 0; + goto recursion_check; if (task != current) goto unknown; if (in_hardirq_stack(stack, info)) - return 0; + goto recursion_check; if (in_softirq_stack(stack, info)) - return 0; + goto recursion_check; + + goto unknown; + +recursion_check: + /* + * Make sure we don't iterate through any given stack more than once. + * If it comes up a second time then there's something wrong going on: + * just break out and report an unknown stack type. + */ + if (visit_mask) { + if (*visit_mask & (1UL << info->type)) + goto unknown; + *visit_mask |= 1UL << info->type; + } + + return 0; unknown: info->type = STACK_TYPE_UNKNOWN; diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 2e708af..8cb6004 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -47,8 +47,7 @@ void stack_type_str(enum stack_type type, const char **begin, const char **end) } } -static bool in_exception_stack(unsigned long *stack, struct stack_info *info, - unsigned long *visit_mask) +static bool in_exception_stack(unsigned long *stack, struct stack_info *info) { unsigned long *begin, *end; struct pt_regs *regs; @@ -64,16 +63,6 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info, if (stack < begin || stack >= end) continue; - /* - * Make sure we don't iterate through an exception stack more - * than once. If it comes up a second time then there's - * something wrong going on - just break out and report an - * unknown stack type. - */ - if (*visit_mask & (1U << k)) - break; - *visit_mask |= 1U << k; - info->type = STACK_TYPE_EXCEPTION + k; info->begin = begin; info->end = end; @@ -119,16 +108,30 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, task = task ? : current; if (in_task_stack(stack, task, info)) - return 0; + goto recursion_check; if (task != current) goto unknown; - if (in_exception_stack(stack, info, visit_mask)) - return 0; + if (in_exception_stack(stack, info)) + goto recursion_check; if (in_irq_stack(stack, info)) - return 0; + goto recursion_check; + + goto unknown; + +recursion_check: + /* + * Make sure we don't iterate through any given stack more than once. + * If it comes up a second time then there's something wrong going on: + * just break out and report an unknown stack type. + */ + if (visit_mask) { + if (*visit_mask & (1UL << info->type)) + goto unknown; + *visit_mask |= 1UL << info->type; + } return 0;