From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964861AbcHDWYV (ORCPT ); Thu, 4 Aug 2016 18:24:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55698 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933954AbcHDWYG (ORCPT ); Thu, 4 Aug 2016 18:24:06 -0400 From: Josh Poimboeuf To: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" Cc: x86@kernel.org, linux-kernel@vger.kernel.org, Andy Lutomirski , Linus Torvalds , Steven Rostedt , Brian Gerst , Kees Cook , Peter Zijlstra , Frederic Weisbecker , Byungchul Park Subject: [PATCH v2 44/44] x86/unwind: warn if stack grows up Date: Thu, 4 Aug 2016 17:22:40 -0500 Message-Id: <71e347ddaefa1b02eee1fd7c73111d8bc584e6de.1470345772.git.jpoimboe@redhat.com> In-Reply-To: References: X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 04 Aug 2016 22:24:01 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a sanity check to ensure the stack only grows down, and print a warning if the check fails. Use printk_deferred_once() because the unwinder can be called with the console lock by lockdep via save_stack_trace(). Signed-off-by: Josh Poimboeuf --- arch/x86/kernel/unwind_frame.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index f943413..a29c342 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c @@ -107,6 +107,7 @@ bool unwind_next_frame(struct unwind_state *state) { struct pt_regs *regs; unsigned long *next_bp; + enum stack_type prev_type = state->stack_info.type; state->regs = NULL; @@ -186,6 +187,15 @@ bool unwind_next_frame(struct unwind_state *state) return false; } + /* make sure the stack only unwinds up */ + if (state->stack_info.type == prev_type && next_bp <= state->bp) { + printk_deferred_once(KERN_WARNING "WARNING: kernel stack frame pointer at %p in %s:%d points the wrong way (%p)\n", + state->bp, state->task->comm, + state->task->pid, next_bp); + state->stack_info.type = STACK_TYPE_UNKNOWN; + return false; + } + /* move to the next frame */ state->bp = next_bp; return true; -- 2.7.4