Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp847361ybj; Thu, 7 May 2020 08:58:00 -0700 (PDT) X-Google-Smtp-Source: APiQypKxI4UAqvSaHLi/QqefADBEKWYeBvW3EH0uvy1OzGZmQE6lcFB7iJFzmoTP1EhrYZsmVimS X-Received: by 2002:a05:6402:1597:: with SMTP id c23mr13226666edv.353.1588867079941; Thu, 07 May 2020 08:57:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588867079; cv=none; d=google.com; s=arc-20160816; b=cf3Qike0Ou6bJgYbtQa7AbMQVT4Jn0KHf2N6wOiaOEdRujOfWU8zQMxtqezwsksnk1 0gxLYKeXMFtKm4soFIanRCMM03i1xoTh6aiGfneA59isme+XBhxZntmRflNx+SKxHADd q5g61NoEUlb6ichnD1aXDo51PXBSFd01mVQkmUSE8J/UO7Lht2TVLIhM4fT7JMzBXhMD CPRmlQfwkSIHekqecYsjwG04o0k1T1WbzgJswQlkyjXLIE+UWmn5JL/+0SOuAwUneJ2Q 6E/QWj24LlIxaW8Dk3LF5j4bJ+qkULSSjvfuG0H44gI9T1CiCtN2bmHxq9zC7Qkz6eCB QtJA== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=sZwayGeIhH37XtpNpr10ynGV50B7j2yfwz01WfjOVQk=; b=GgvPcbRH6eCOn9104Z89CZkLNvQQ8MDrpkvxPDL/bGgxM2HaRB+upvUTkejWcQaqfZ +kfvCwNiQ3gevfI2ViEPSPRsNvlBIUBt6CzVTWLK1k1iLznQLJZPd1A4LhyYAXyhQr7W xePiMRNBcUUHTnbK52G7ViomUANrgDNgc0e3yYnH/UrG4Bq8DsKGW5J0O1HB0edLQWeM Vu2WTLXNyOZBqQavqQPHLN8Gj76pAOHbY2+ewLfkcPOuAgH8ePjx6jByXqMBRQz/g/Si JRzWUzcvZ0AA4GNrKDaQ3vGPvnhpoWBpoJpdYJaatUG1ZdKzGKg4pByLBEk5NKnsH7SS 8hqw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g24si3258319ejb.433.2020.05.07.08.57.34; Thu, 07 May 2020 08:57:59 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726778AbgEGP4D (ORCPT + 99 others); Thu, 7 May 2020 11:56:03 -0400 Received: from mga05.intel.com ([192.55.52.43]:37587 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726451AbgEGP4D (ORCPT ); Thu, 7 May 2020 11:56:03 -0400 IronPort-SDR: cYuW9XjfF8SP2WsfFQGuGAs+NYZ5PyzuhtKq3zF9Xvg2GNXerz+H3C+0kkJ/8Hnru8DpQtkmb5 paSzTklkOl2Q== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 May 2020 08:56:01 -0700 IronPort-SDR: Rl/sOx0blX5R3Ymsdvdbhlt3kD3ZMVWetPE/eMqU5p97aaNBAiLnHmbTxBJp5qBpYX32MBW0nF Xhx1IdTGHvAA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,364,1583222400"; d="scan'208";a="263980638" Received: from yyu32-desk.sc.intel.com ([143.183.136.146]) by orsmga006.jf.intel.com with ESMTP; 07 May 2020 08:56:00 -0700 From: Yu-cheng Yu To: linux-kernel@vger.kernel.org, x86@kernel.org, "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , Dave Hansen , Tony Luck , Andy Lutomirski , Borislav Petkov , Rik van Riel , "Ravi V. Shankar" , Sebastian Andrzej Siewior , Fenghua Yu , Peter Zijlstra Cc: Yu-cheng Yu Subject: [PATCH v3 06/10] x86/fpu/xstate: Update sanitize_restored_xstate() for supervisor xstates Date: Thu, 7 May 2020 08:55:16 -0700 Message-Id: <20200507155516.25972-1-yu-cheng.yu@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200328164307.17497-7-yu-cheng.yu@intel.com> References: <20200328164307.17497-7-yu-cheng.yu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The function sanitize_restored_xstate() sanitizes user xstates of an XSAVE buffer by clearing bits not in the input 'xfeatures' from the buffer's header->xfeatures, effectively resetting those features back to the init state. When supervisor xstates are introduced, it is necessary to make sure only user xstates are sanitized. Ensure supervisor bits in header->xfeatures stay set and supervisor states are not modified. To make names clear, also: - Rename the function to sanitize_restored_user_xstate(). - Rename input parameter 'xfeatures' to 'user_xfeatures'. - In __fpu__restore_sig(), rename 'xfeatures' to 'user_xfeatures'. Signed-off-by: Yu-cheng Yu Reviewed-by: Dave Hansen --- v3: - Change xfeatures_user to user_xfeatures. arch/x86/kernel/fpu/signal.c | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index cd6eafba12da..d09d72334a12 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -211,9 +211,9 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) } static inline void -sanitize_restored_xstate(union fpregs_state *state, - struct user_i387_ia32_struct *ia32_env, - u64 xfeatures, int fx_only) +sanitize_restored_user_xstate(union fpregs_state *state, + struct user_i387_ia32_struct *ia32_env, + u64 user_xfeatures, int fx_only) { struct xregs_state *xsave = &state->xsave; struct xstate_header *header = &xsave->header; @@ -226,13 +226,22 @@ sanitize_restored_xstate(union fpregs_state *state, */ /* - * Init the state that is not present in the memory - * layout and not enabled by the OS. + * 'user_xfeatures' might have bits clear which are + * set in header->xfeatures. This represents features that + * were in init state prior to a signal delivery, and need + * to be reset back to the init state. Clear any user + * feature bits which are set in the kernel buffer to get + * them back to the init state. + * + * Supervisor state is unchanged by input from userspace. + * Ensure supervisor state bits stay set and supervisor + * state is not modified. */ if (fx_only) header->xfeatures = XFEATURE_MASK_FPSSE; else - header->xfeatures &= xfeatures; + header->xfeatures &= user_xfeatures | + xfeatures_mask_supervisor(); } if (use_fxsr()) { @@ -281,7 +290,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) struct task_struct *tsk = current; struct fpu *fpu = &tsk->thread.fpu; struct user_i387_ia32_struct env; - u64 xfeatures = 0; + u64 user_xfeatures = 0; int fx_only = 0; int ret = 0; @@ -314,7 +323,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) trace_x86_fpu_xstate_check_failed(fpu); } else { state_size = fx_sw_user.xstate_size; - xfeatures = fx_sw_user.xfeatures; + user_xfeatures = fx_sw_user.xfeatures; } } @@ -349,7 +358,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) */ fpregs_lock(); pagefault_disable(); - ret = copy_user_to_fpregs_zeroing(buf_fx, xfeatures, fx_only); + ret = copy_user_to_fpregs_zeroing(buf_fx, user_xfeatures, fx_only); pagefault_enable(); if (!ret) { fpregs_mark_activate(); @@ -362,7 +371,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) if (use_xsave() && !fx_only) { - u64 init_bv = xfeatures_mask_user() & ~xfeatures; + u64 init_bv = xfeatures_mask_user() & ~user_xfeatures; if (using_compacted_format()) { ret = copy_user_to_xstate(&fpu->state.xsave, buf_fx); @@ -375,12 +384,13 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) if (ret) goto err_out; - sanitize_restored_xstate(&fpu->state, envp, xfeatures, fx_only); + sanitize_restored_user_xstate(&fpu->state, envp, user_xfeatures, + fx_only); fpregs_lock(); if (unlikely(init_bv)) copy_kernel_to_xregs(&init_fpstate.xsave, init_bv); - ret = copy_kernel_to_xregs_err(&fpu->state.xsave, xfeatures); + ret = copy_kernel_to_xregs_err(&fpu->state.xsave, user_xfeatures); } else if (use_fxsr()) { ret = __copy_from_user(&fpu->state.fxsave, buf_fx, state_size); @@ -389,7 +399,8 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) goto err_out; } - sanitize_restored_xstate(&fpu->state, envp, xfeatures, fx_only); + sanitize_restored_user_xstate(&fpu->state, envp, + user_xfeatures, fx_only); fpregs_lock(); if (use_xsave()) { -- 2.21.0