From patchwork Tue Jun 4 18:53:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10975935 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1FBE192A for ; Tue, 4 Jun 2019 18:54:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D84F287A5 for ; Tue, 4 Jun 2019 18:54:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01990287AD; Tue, 4 Jun 2019 18:54:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AB68287A5 for ; Tue, 4 Jun 2019 18:54:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726463AbfFDSyB (ORCPT ); Tue, 4 Jun 2019 14:54:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:54174 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726261AbfFDSyA (ORCPT ); Tue, 4 Jun 2019 14:54:00 -0400 Received: from sol.localdomain (c-24-5-143-220.hsd1.ca.comcast.net [24.5.143.220]) (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 F1E782075C; Tue, 4 Jun 2019 18:53:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559674440; bh=Cp6VeCqZCzW+nl+JJJp4Ag83997W0UrXA7j/yyUXqCw=; h=Date:From:To:Cc:Subject:From; b=Hz4F5IAWX5K7ns5/iauYd6ztC2uFH45l1oTRY+3CZ9LVNjvf+Wc4JueKy6VVfTQzD mnlH5aQ8RPlnFpo1TAQeptBSMvVYdAvE1MxukfkctfinBCwhR7iI+5A4OtOts4fTDD 8nJ2aS2GQoARjwQdpfnL9rkq56s1TjtwvCiG7vaI= Date: Tue, 4 Jun 2019 11:53:58 -0700 From: Eric Biggers To: Sebastian Andrzej Siewior Cc: Borislav Petkov , Dave Hansen , Thomas Gleixner , Andy Lutomirski , "H. Peter Anvin" , Ingo Molnar , Jann Horn , "Jason A. Donenfeld" , kvm ML , Paolo Bonzini , Radim =?utf-8?b?S3LEjW3DocWZ?= , Rik van Riel , x86-ml , linux-kernel@vger.kernel.org Subject: [5.2 regression] copy_fpstate_to_sigframe() change causing crash in 32-bit process Message-ID: <20190604185358.GA820@sol.localdomain> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.12.0 (2019-05-25) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On latest Linus' tree I'm getting a crash in a 32-bit Wine process. I bisected it to the following commit: commit 39388e80f9b0c3788bfb6efe3054bdce0c3ead45 Author: Sebastian Andrzej Siewior Date: Wed Apr 3 18:41:35 2019 +0200 x86/fpu: Don't save fxregs for ia32 frames in copy_fpstate_to_sigframe() Reverting the commit by applying the following diff makes the problem go away. Apparently the problem is that save_fsave_header() assumes the registers have been saved to fpu->state.fxsave, yet the code that does so was removed. Note, bisection was not straightforward because there was another bug also causing a crash temporarily introduced during the FPU code rework: commit 39ea9baffda9 ("x86/fpu: Remove fpu->initialized usage in __fpu__restore_sig()") forgot to call fpstate_init() on the temporary 'state' buffer, so XCOMP_BV_COMPACTED_FORMAT was never set, causing xrstors to fail. But that bug went away in later commits. - Eric diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 5a8d118bc423e..ed16a24aab497 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -157,6 +157,7 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) */ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) { + struct fpu *fpu = ¤t->thread.fpu; struct task_struct *tsk = current; int ia32_fxstate = (buf != buf_fx); int ret; @@ -202,6 +203,10 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) return -EFAULT; } + /* Update the thread's fxstate to save the fsave header. */ + if (ia32_fxstate) + copy_fxregs_to_kernel(fpu); + /* Save the fsave header for the 32-bit frames. */ if ((ia32_fxstate || !use_fxsr()) && save_fsave_header(tsk, buf)) return -1;