From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793213073; b=Wfnbc3y6AFT+t5ougU73jiqDi4Sx9UTZZlC8/amdvL217OuPi6exA9S1Kum8/qktakxL b/qVZ5tQ838cBqasbYfKZMH5oLMBFQ9lSchOr7Alr9KjD92UpQyw7fqugBTmXUGuPATDW x9eNLmHgxqdRH+uP77DdoZG9LJESdZYTkvw0EIuGm4DHjaZjMw2i3O4Jli7hZzWgymBPD eMsotnQT63zE7vrE7slBtJyk7bRC9/SUb5TMpWYmSFg/cW6/bt/2j73mMU25+g7DcDZZ+ r1DPCeLCD4kyKuDhFate+4Fl0D1Vrdd4GhRB5VDXyGacocKVdrLG1lU4AfNM1vqurkA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793213073; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=k9oR8naec3gWp7E316Dcw3iCqVHsftv1I7SHfKiavdA=; b=KDRPApa3pL4b+VJH7s43C+rCqM6AaCqOxG33oRmGCm85gw5YfQrl/5E2Q6xAJLD//HKh 4OqTQd+l9e/B4an6csQG3G1vrq7ihUU9iAg0tFsRAlCeQHcG3/5Ve5feiD2XA38cSQq+N Ldva/0o3n+3wtPy+XN9sPFcqC2xQvzCVCSEMGJHVIRvrOIz1xogxGgYemMAME1l81a+6D s480y11iIQJ2GUcrkX8zF9qLqLdiEW+/E06YESsqg4ZiCi/HKwBgHhLxbYkxc1s5yS69D vqMQW8nTLQnlxBoFY4lRzoMd68VCtgNOKsJwUlIo/1rxvVuvKm+hKB2eXAeRVg7dHeQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=ZIuSnpiU; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 201F7606A325; Wed, 28 Oct 2026 18:44:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=ZIuSnpiU Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3B8D51F01825; Wed, 28 Oct 2026 18:44:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1793213072; bh=k9oR8naec3gWp7E316Dcw3iCqVHsftv1I7SHfKiavdA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ZIuSnpiUAxXix3vhzVZ/7OVuGJVjfh0V3u9Kg3n8oa6K4On6cRcXpDopDTq2ad91+ 7pCDXjorXV1Y8V5LPQb1eTlMVFKHTdzMe4TriP2C7tapmb7cx2IGCRZc/B0CscJ70W 53jjabVfec7UlXI3aRphNiNRAJ+Bq0/G9Bpnn1C0= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Mark Rutland , Mark Brown , Catalin Marinas , Will Deacon , Sasha Levin Subject: [PATCH 6.1 0376/1887] arm64/fpsimd: signal: Forbid non-streaming SVE payload on SME-only systems Date: Wed, 28 Oct 2026 17:41:12 +0100 Message-ID: <20261028170507.788932741@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261028170459.200466217@linuxfoundation.org> References: <20261028170459.200466217@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mark Rutland [ Upstream commit e060d9069b49fe55f38057dfe592068014652671 ] When system_supports_sme() is true but system_supports_sve() is false, restoring a specifically crafted SVE signal context can result in the task erroneously having non-streaming SVE state. Subsequent attempts to manipulate the task's FPSIMD/SVE/SME state can result in a variety of problems, including fatal EL1 UNDEFs. In such configurations, the kernel always creates an SVE signal context when delivering a signal, and this can only be in one of two states: (1) SVE_SIG_FLAG_SM is set, and an SVE payload is present containing streaming mode SVE state. The recorded VL is the task's live streaming VL. (2) SVE_SIG_FLAG_SM is clear, and an SVE payload is not present. The FPSIMD context contains the non-streaming mode FPSIMD state. The recorded VL is 0. Currently restore_sve_fpsimd_context() correctly rejects cases where SVE_SIG_FLAG_SM is set and an SVE payload is not present, but fails to reject cases where SVE_SIG_FLAG_SM is clear and an SVE payload is present. Consequently, restore_sve_fpsimd_context() can place the task in a state where it has non-streaming SVE state even when this is not supported by HW. For example, this can cause a later EL1 UNDEF when the kernel attempts to restore the task's ZCR_EL1 value: | # ./sme-sigcontext-to-sve | Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP | Modules linked in: | CPU: 0 UID: 0 PID: 131 Comm: sme-sigcontext- Not tainted 7.3.0-rc1 #1 PREEMPT | Hardware name: linux,dummy-virt (DT) | pstate: 61402009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) | pc : fpsimd_restore_current_state+0x258/0x458 | lr : exit_to_user_mode_loop+0xb8/0x188 | sp : ffff80008056be40 | x29: ffff80008056be40 x28: fff00000c1670000 x27: 0000000000000000 | x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000 | x23: ffff80008056bec0 x22: 0000000000000008 x21: 0000000000000040 | x20: 0000000000000081 x19: 0000000008800010 x18: 0000000000000000 | x17: 0000fffffd412570 x16: 0000000000001000 x15: 0000fffffd4123b0 | x14: 0000fffffd412780 x13: 0000fffffd412be8 x12: 0000000047435300 | x11: 0000fffffd412570 x10: 0000000000000000 x9 : 0000000045585401 | x8 : fff00000c18a6c44 x7 : 0000000000000000 x6 : 0000000000000002 | x5 : 0000000000000002 x4 : ffff800080568000 x3 : 0000000000000001 | x2 : 0000000008800010 x1 : fff00000c1670000 x0 : 0000000008800000 | Call trace: | fpsimd_restore_current_state+0x258/0x458 (P) | exit_to_user_mode_loop+0xb8/0x188 | el0_svc+0x1cc/0x1d0 | el0t_64_sync_handler+0xa0/0xe4 | el0t_64_sync+0x198/0x19c | Code: d5384101 f9400020 53175c03 36b80de0 (d5381202) | ---[ end trace 0000000000000000 ]--- | Kernel panic - not syncing: Oops - Undefined instruction: Fatal exception in interrupt | Kernel Offset: 0x291fb1000000 from 0xffff800080000000 | PHYS_OFFSET: 0x40000000 | CPU features: 0x0,00000000,0052802f,ffb88f43,3afcf73f | Memory Limit: none Rework restore_sve_fpsimd_context() to reject cases where SVE_SIG_FLAG_SM is clear and an SVE payload is not present. As parse_user_sigframe() rejects SVE signal frames when neither SVE nor SME are supported, it isn't necessary for restore_sve_fpsimd_context() to handle the case where neither are supported. Fixes: 7dde62f0687c ("arm64/signal: Always accept SVE signal frames on SME only systems") Signed-off-by: Mark Rutland Reviewed-by: Mark Brown Cc: Catalin Marinas Cc: Will Deacon Cc: stable@vger.kernel.org Signed-off-by: Will Deacon [ sashal: Used the copied sve.head.size instead of the unavailable user->sve_size field. ] Signed-off-by: Sasha Levin --- arch/arm64/kernel/signal.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 9fd7f78d11d1e..b00bf1a415400 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -271,22 +271,37 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) unsigned int vl, vq; struct user_fpsimd_state fpsimd; struct sve_context sve; + bool fpsimd_only; if (__copy_from_user(&sve, user->sve, sizeof(sve))) return -EFAULT; + fpsimd_only = (sve.head.size <= sizeof(*user->sve)); + if (sve.flags & SVE_SIG_FLAG_SM) { if (!system_supports_sme()) return -EINVAL; + /* + * Streaming SVE state is always preserved with an SVE payload. + * Only accept streaming state which has an SVE payload. + */ + if (fpsimd_only) + return -EINVAL; + vl = task_get_sme_vl(current); } else { /* - * A SME only system use SVE for streaming mode so can - * have a SVE formatted context with a zero VL and no - * payload data. + * Non-streaming SVE state may be preserved without an SVE + * payload, in which case all state is saved in the FPSIMD + * context. + * + * On SME-only systems, non-streaming (FPSIMD-only) state is + * always preserved without an SVE payload, and with VL==0. On + * such systems, only accept non-streaming state without an SVE + * payload. */ - if (!system_supports_sve() && !system_supports_sme()) + if (!system_supports_sve() && !fpsimd_only) return -EINVAL; vl = task_get_sve_vl(current); @@ -295,7 +310,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) if (sve.vl != vl) return -EINVAL; - if (sve.head.size <= sizeof(*user->sve)) { + if (fpsimd_only) { clear_thread_flag(TIF_SVE); current->thread.svcr &= ~SVCR_SM_MASK; current->thread.fp_type = FP_STATE_FPSIMD; -- 2.53.0