Received: by 2002:ac0:98c7:0:0:0:0:0 with SMTP id g7-v6csp2452870imd; Fri, 2 Nov 2018 11:39:11 -0700 (PDT) X-Google-Smtp-Source: AJdET5f6E9EvyUYIbazyfZ2XG4WMqOIYnej2GLh3XhcA9s2SXD1beEXRAr1tp5WIC4d2brVjKdWY X-Received: by 2002:a63:f210:: with SMTP id v16-v6mr11506607pgh.371.1541183951861; Fri, 02 Nov 2018 11:39:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1541183951; cv=none; d=google.com; s=arc-20160816; b=OCCexclrSwrL6xEf5bA8j+zFncr1xvbR+cwX31OR7/IRx43xE78gGwBvFsTYOKlZbl EzYHsGP7fceJ8KpRrPRRzhNSzDcvijbDjG+ttWkCUlp/nDSylsS3JXljdhu6+ymPwjZt QQOqu3SRhP6FWiVNkW5MJPhtIXhBxS0jf5iFRmpZpWbUpU4YmuLH+3xANwLe8I4oaMrH AT00VbtUvD9nlNAe6zrEzpJNQVzsCI85hcxFPpAnX2xlSPdvNH6SlpdeO1OJOz4PhHR/ QA9kUPzuxv/QCSSL5VoR1jWxKXNO6U3yvYab1RSAthNWRvVn7C/MDE2NwX1saxNJGvay dT/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=YuW6W2acZUyNd3uQzGj4nG8M+Pqv7p83CHchvrcsBsE=; b=bO5B/UACxKjHrB+i5knWs0Y625BNcmnq0uHQt/yTjCh2M7luSxztPM+vmP7+qUICzP pCbKnoKTPui7kmYIJxKshNYrrTlRF7Ejp6FzYQRUOxziw0l/Q70Araf02oEKIaz8Klvh ivWWJHUBFbIVY58gSfjCDdcmf8jKmH62W73QenIQ8BVRO85VsdOC65ShnIAPDekczyJ/ giQDYkAZUQBpy2VGWyMhuN2HYKek5ocIOLA93DM3sKkFZ4oUMfw+Lk/PXKnUAbPr+DHW THi8xtXgccObt8PlnklmwsfhKQKq5PRM2JOB1zjviD+TXFbwlA8SNvlnMJkJksDTDf1C 3h8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=xBvQTtbd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d17si533651pgl.484.2018.11.02.11.38.57; Fri, 02 Nov 2018 11:39:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=xBvQTtbd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728688AbeKCDqD (ORCPT + 99 others); Fri, 2 Nov 2018 23:46:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:39726 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727556AbeKCDqD (ORCPT ); Fri, 2 Nov 2018 23:46:03 -0400 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 48D042081B; Fri, 2 Nov 2018 18:37:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1541183871; bh=1munvivSvgrJQgCu5VchE2mJMZTLOcZwFPFg8BWjYRA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xBvQTtbdMD1CC+guxxRtqoaZFkiI8xpWV1WsLS2vfA/x+phcqCj0MmE5oKmotW9Cz rP0YFcJJMrW/lg7d9O/5uUjfkTPowfCiqhhOG6urWWsNiG90ke30fCY4GfYnR/401I b3NRE6IWjpSyd5j04iRORxEoesvf5IvR+55Nwt4M= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "David S. Miller" Subject: [PATCH 4.19 22/24] sparc64: Make corrupted user stacks more debuggable. Date: Fri, 2 Nov 2018 19:34:55 +0100 Message-Id: <20181102182843.141095174@linuxfoundation.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181102182839.725385066@linuxfoundation.org> References: <20181102182839.725385066@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: David Miller [ Upstream commit 5b4fc3882a649c9411dd0dcad2ddb78e911d340e ] Right now if we get a corrupted user stack frame we do a do_exit(SIGILL) which is not helpful. If under a debugger, this behavior causes the inferior process to exit. So the register and other state cannot be examined at the time of the event. Instead, conditionally log a rate limited kernel log message and then force a SIGSEGV. With bits and ideas borrowed (as usual) from powerpc. Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- arch/sparc/include/asm/switch_to_64.h | 3 ++- arch/sparc/kernel/process_64.c | 25 +++++++++++++++++++------ arch/sparc/kernel/rtrap_64.S | 1 + arch/sparc/kernel/signal32.c | 12 ++++++++++-- arch/sparc/kernel/signal_64.c | 6 +++++- 5 files changed, 37 insertions(+), 10 deletions(-) --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h @@ -67,6 +67,7 @@ do { save_and_clear_fpu(); \ } while(0) void synchronize_user_stack(void); -void fault_in_user_windows(void); +struct pt_regs; +void fault_in_user_windows(struct pt_regs *); #endif /* __SPARC64_SWITCH_TO_64_H */ --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -521,7 +522,12 @@ static void stack_unaligned(unsigned lon force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) sp, 0, current); } -void fault_in_user_windows(void) +static const char uwfault32[] = KERN_INFO \ + "%s[%d]: bad register window fault: SP %08lx (orig_sp %08lx) TPC %08lx O7 %08lx\n"; +static const char uwfault64[] = KERN_INFO \ + "%s[%d]: bad register window fault: SP %016lx (orig_sp %016lx) TPC %08lx O7 %016lx\n"; + +void fault_in_user_windows(struct pt_regs *regs) { struct thread_info *t = current_thread_info(); unsigned long window; @@ -534,9 +540,9 @@ void fault_in_user_windows(void) do { struct reg_window *rwin = &t->reg_window[window]; int winsize = sizeof(struct reg_window); - unsigned long sp; + unsigned long sp, orig_sp; - sp = t->rwbuf_stkptrs[window]; + orig_sp = sp = t->rwbuf_stkptrs[window]; if (test_thread_64bit_stack(sp)) sp += STACK_BIAS; @@ -547,8 +553,16 @@ void fault_in_user_windows(void) stack_unaligned(sp); if (unlikely(copy_to_user((char __user *)sp, - rwin, winsize))) + rwin, winsize))) { + if (show_unhandled_signals) + printk_ratelimited(is_compat_task() ? + uwfault32 : uwfault64, + current->comm, current->pid, + sp, orig_sp, + regs->tpc, + regs->u_regs[UREG_I7]); goto barf; + } } while (window--); } set_thread_wsaved(0); @@ -556,8 +570,7 @@ void fault_in_user_windows(void) barf: set_thread_wsaved(window + 1); - user_exit(); - do_exit(SIGILL); + force_sig(SIGSEGV, current); } asmlinkage long sparc_do_fork(unsigned long clone_flags, --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -39,6 +39,7 @@ __handle_preemption: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate __handle_user_windows: + add %sp, PTREGS_OFF, %o0 call fault_in_user_windows 661: wrpr %g0, RTRAP_PSTATE, %pstate /* If userspace is using ADI, it could potentially pass --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -371,7 +371,11 @@ static int setup_frame32(struct ksignal get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) { - do_exit(SIGILL); + if (show_unhandled_signals) + pr_info("%s[%d] bad frame in setup_frame32: %08lx TPC %08lx O7 %08lx\n", + current->comm, current->pid, (unsigned long)sf, + regs->tpc, regs->u_regs[UREG_I7]); + force_sigsegv(ksig->sig, current); return -EINVAL; } @@ -501,7 +505,11 @@ static int setup_rt_frame32(struct ksign get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) { - do_exit(SIGILL); + if (show_unhandled_signals) + pr_info("%s[%d] bad frame in setup_rt_frame32: %08lx TPC %08lx O7 %08lx\n", + current->comm, current->pid, (unsigned long)sf, + regs->tpc, regs->u_regs[UREG_I7]); + force_sigsegv(ksig->sig, current); return -EINVAL; } --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -370,7 +370,11 @@ setup_rt_frame(struct ksignal *ksig, str get_sigframe(ksig, regs, sf_size); if (invalid_frame_pointer (sf)) { - do_exit(SIGILL); /* won't return, actually */ + if (show_unhandled_signals) + pr_info("%s[%d] bad frame in setup_rt_frame: %016lx TPC %016lx O7 %016lx\n", + current->comm, current->pid, (unsigned long)sf, + regs->tpc, regs->u_regs[UREG_I7]); + force_sigsegv(ksig->sig, current); return -EINVAL; }