From patchwork Tue Jun 25 14:57:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13711449 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A08B2C30658 for ; Tue, 25 Jun 2024 15:03:43 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7D2856B00B9; Tue, 25 Jun 2024 11:03:41 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 72F8F6B00BB; Tue, 25 Jun 2024 11:03:41 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 582656B00BC; Tue, 25 Jun 2024 11:03:41 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 289756B00B9 for ; Tue, 25 Jun 2024 11:03:41 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id CEE9D1A0205 for ; Tue, 25 Jun 2024 15:03:40 +0000 (UTC) X-FDA: 82269730200.19.3362E3E Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by imf16.hostedemail.com (Postfix) with ESMTP id 6300F180030 for ; Tue, 25 Jun 2024 15:03:35 +0000 (UTC) Authentication-Results: imf16.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=abiwsMY7; spf=pass (imf16.hostedemail.com: domain of broonie@kernel.org designates 145.40.73.55 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=none) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1719327803; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=LB2f067LJFvydnOND1bFIwkYnAf0/uOqfDmyYeKI5+w=; b=KpLyGdxPxxQVB5w39J1JU4aXfLRFfOP5FEKyoHw80Zfdni5/ObxNaROdsmX7wR8tk92BX9 Wo1QgunDr+qFDlGWVidZ6QLqIqrZt5xST9ZDkvj6Ddl+VANtj/KUYXaKPI65TXR0Gf5eMd hmIQZ3qf6fmO8XCq2glenNvLv5Cx5mA= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1719327803; a=rsa-sha256; cv=none; b=pbN21ut3ebrNV4jxtmDWYfbzv32Wwbf9c8+erBnq28F7XZS+GE/Q1MM0u92AnSb/xqpjbU 5e8KQ0whA4DLIMJaJxQQ5vKPB7BdeZmKmxzkRhXLdIRXWWZvg6vgNGQe/Bdj1ojKdQZb53 iJxYfWIMFqiZ9X9gJCsPLOZ7gvNfbrs= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=abiwsMY7; spf=pass (imf16.hostedemail.com: domain of broonie@kernel.org designates 145.40.73.55 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=none) header.from=kernel.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 43052CE1B78; Tue, 25 Jun 2024 15:03:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 367EBC4AF09; Tue, 25 Jun 2024 15:03:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719327812; bh=CZyk2Foz6/MDwSr5OV2kQ3tmU9mYoHXOdRBxLAAsKpQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=abiwsMY7+KvzHS4P9PmFpFGCEhgfRkYRU7IEtlsNfXBRypV5ugB2bGrkEJVvM8I4j 9jcbbyT2tLv5vZNCVrPo4QacHCxBo49K7KyoRyuf5AaoLK297ouS0MCDrgjsNC+cxJ ar6ISZYKU+e5OttraAVt88d998Ryen6dnW5Z6k24XXjBNpV4RH6erpy6S89sxCTMhF FGk7xs+oq90NGpEM3Ur5oVqrHGiAM08LqTGvs1dVIusEI0L4vPAwF9t0nEhDp6iwP0 UgkHCwtpKQ1h0ZvO+E1ISnbEf6yvg0H0J6gZDCvrs3SSZF4PTWcs/Ypo3CRVhKdl0G 8CxEaKwvgepOA== From: Mark Brown Date: Tue, 25 Jun 2024 15:57:52 +0100 Subject: [PATCH v9 24/39] arm64/signal: Expose GCS state in signal frames MIME-Version: 1.0 Message-Id: <20240625-arm64-gcs-v9-24-0f634469b8f0@kernel.org> References: <20240625-arm64-gcs-v9-0-0f634469b8f0@kernel.org> In-Reply-To: <20240625-arm64-gcs-v9-0-0f634469b8f0@kernel.org> To: Catalin Marinas , Will Deacon , Jonathan Corbet , Andrew Morton , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Arnd Bergmann , Oleg Nesterov , Eric Biederman , Shuah Khan , "Rick P. Edgecombe" , Deepak Gupta , Ard Biesheuvel , Szabolcs Nagy , Kees Cook Cc: "H.J. Lu" , Paul Walmsley , Palmer Dabbelt , Albert Ou , Florian Weimer , Christian Brauner , Thiago Jung Bauermann , Ross Burton , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Brown X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=6094; i=broonie@kernel.org; h=from:subject:message-id; bh=CZyk2Foz6/MDwSr5OV2kQ3tmU9mYoHXOdRBxLAAsKpQ=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmetuF7m/PmlelddEg/bBFW5FD/h5PxHRPz1T4ZL/z fGWGm8+JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZnrbhQAKCRAk1otyXVSH0PsAB/ 43/MMGsHECfy2LfiwF5beeX/KzMJ+QU6tHv9Rsszt32thb32vCsuGfKKH71Xe+3E247nIHvEtd7KWo 7CwsIx7fNvbl16Me6s6NdDzluCb6pKjVw9XCUQUwwVFDVuIkDVk6azKRlXnn5W8r4K0uSyqiyAAulY x0W2qVfgGP5KrrZ0PuIpTSNi/DEec8WvurCvULvwfQyuvqZd9YSZNkmIJ0ruD1syAofnCIIrmQSUdP ueVupKXYI60989eIQZmtXS92XE9GTHjq2fl7FlGX36E7MyL3KSo5mV46Q/dNNDctkUc+1bhwk2bdsM zbLzeHeBTZytsjveH0XBKROeaAjqZy X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Rspamd-Queue-Id: 6300F180030 X-Stat-Signature: o7s15w8u51517wzgm7txqs7w5h11p9ta X-Rspamd-Server: rspam09 X-Rspam-User: X-HE-Tag: 1719327815-895506 X-HE-Meta: U2FsdGVkX1/4Goh9jB5xZ2fjzXynKwJLv+k+Wsq3off+D4Baf71d6QQjnWCp3TAK5qew+J+k36yRsueDWUnPoeW5mhn55ukelRkXBawq4WVW4P9J6TfvPdvhCcnl2gzw3VQKLDCXxIXH6jh/3DItptb66UOj/iVHse0pkWapbbiXg4HO0MW9+7Rgp8aiun86wwOKS3fL5pL8lXuFpkMlbf3IDsFr67fEqoJU+V+ZlQZcehoWzgVOCf6VMHcW9eLoIXuGmuYHXIQpJ4bwEZeksBjL1miRovcUHBYSgXEkO5bG06px7A/TZV7npBxZ6cwO2JfRWlOXRDrwVc4EcUWiWbGNFFXqyhd/8FbbaZX2M+esoDdkNf07L9YSWVQ8iyWra/onjmHMqL3A96ld5py4nBeFmbwQy+MOq5OHOiDgU1xAw0ze9yzG356wxrJDVL4vEPMdvMnvq9lVyRQm/WbK2jNIECwcX9uFagnGgGAQQRT3A8Y1EY+MmmUjGKbY5VhOQET9VWv5f8M1FMOlgXKxUghW3TlgHPnFdjG8cK1jmooQvD2aMm+gcrjZtJ3x8K+s5jWfnnMTLUAlKlMus31u8/0Pfdt9zvtblTS8ef8/5DgYu0fjPih8GsU4kOt+XKEMbS0LF1Jk9JXzfWqenWdgbK2/Zpdl2IbSjLL3BQ2SBxGwlMPPWdb9CHK3aMA2IW+2oldy9OimmAkMdJMlJMMndH2W65M1e2/EoyRkqbuCuIzjf7vz+KF+t4oH3JOejLCVg9YFeBd25G1T5ag/FGtR3AXfJRdyzue1ZF7ryKJ63lNdM2Yca5rt4bQoWani2+FwRNfobP5Xv7j1JbhJvBevwSxAe0dr5ADbqiNVMwpIVA6NoI2yaKLCvQRakatOlfq8C1CsNKnPPbDIWblhu0v2/D+lSKQqrHoMcZFKtnM5P1fDTbFFCEve+3PHXGXUxqs9r7comnEtMCX2dTU1iu8 cUuUl628 wnCY9NT3WqIqduQKoGcWql+3LOYfdR7q4KMlPs8xKkqYOiK05v8IqsuLTH5NyRXUlS/4LRqldklbyIhuk3Z1mwe/exVFs2F1PF7WwvfnyHR43Wu4fwHCrHpP1QddU0r/YWhgMszfT0aGxFBr/tsSJNk3UGuPXIRA9ERQAP1ns2L659H9ZSw2dT//P9H3M9klxaG0ecJeGQgRlLt7TfbJt0jKkIAP3TbaM7PeJyDwwI5STlbRkHy36kA7ndA2n4+IIRVe+aEYsTMOhvzfFlQWzjUCY9ACZsTke7ZtDtXRrmcA2V9a3nbhYlb5awLw3FVyKgPFn5Ng0NSlTMCgZhquaTp2gKwHEvuankuJ9qnJCXrbxHO+foNWNWJLbXP8140MvVu+V X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add a context for the GCS state and include it in the signal context when running on a system that supports GCS. We reuse the same flags that the prctl() uses to specify which GCS features are enabled and also provide the current GCS pointer. We do not support enabling GCS via signal return, there is a conflict between specifying GCSPR_EL0 and allocation of a new GCS and this is not an ancticipated use case. We also enforce GCS configuration locking on signal return. Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- arch/arm64/include/uapi/asm/sigcontext.h | 9 +++ arch/arm64/kernel/signal.c | 108 +++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h index 8a45b7a411e0..c2d61e8efc84 100644 --- a/arch/arm64/include/uapi/asm/sigcontext.h +++ b/arch/arm64/include/uapi/asm/sigcontext.h @@ -176,6 +176,15 @@ struct zt_context { __u16 __reserved[3]; }; +#define GCS_MAGIC 0x47435300 + +struct gcs_context { + struct _aarch64_ctx head; + __u64 gcspr; + __u64 features_enabled; + __u64 reserved; +}; + #endif /* !__ASSEMBLY__ */ #include diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index a1e0aa38bff9..f034a1a1d194 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -88,6 +88,7 @@ struct rt_sigframe_user_layout { unsigned long fpsimd_offset; unsigned long esr_offset; + unsigned long gcs_offset; unsigned long sve_offset; unsigned long tpidr2_offset; unsigned long za_offset; @@ -217,6 +218,8 @@ struct user_ctxs { u32 zt_size; struct fpmr_context __user *fpmr; u32 fpmr_size; + struct gcs_context __user *gcs; + u32 gcs_size; }; static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) @@ -636,6 +639,83 @@ extern int restore_zt_context(struct user_ctxs *user); #endif /* ! CONFIG_ARM64_SME */ +#ifdef CONFIG_ARM64_GCS + +static int preserve_gcs_context(struct gcs_context __user *ctx) +{ + int err = 0; + u64 gcspr; + + /* + * We will add a cap token to the frame, include it in the + * GCSPR_EL0 we report to support stack switching via + * sigreturn. + */ + gcs_preserve_current_state(); + gcspr = current->thread.gcspr_el0; + if (task_gcs_el0_enabled(current)) + gcspr -= 8; + + __put_user_error(GCS_MAGIC, &ctx->head.magic, err); + __put_user_error(sizeof(*ctx), &ctx->head.size, err); + __put_user_error(gcspr, &ctx->gcspr, err); + __put_user_error(0, &ctx->reserved, err); + __put_user_error(current->thread.gcs_el0_mode, + &ctx->features_enabled, err); + + return err; +} + +static int restore_gcs_context(struct user_ctxs *user) +{ + u64 gcspr, enabled; + int err = 0; + + if (user->gcs_size != sizeof(*user->gcs)) + return -EINVAL; + + __get_user_error(gcspr, &user->gcs->gcspr, err); + __get_user_error(enabled, &user->gcs->features_enabled, err); + if (err) + return err; + + /* Don't allow unknown modes */ + if (enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK) + return -EINVAL; + + err = gcs_check_locked(current, enabled); + if (err != 0) + return err; + + /* Don't allow enabling */ + if (!task_gcs_el0_enabled(current) && + (enabled & PR_SHADOW_STACK_ENABLE)) + return -EINVAL; + + /* If we are disabling disable everything */ + if (!(enabled & PR_SHADOW_STACK_ENABLE)) + enabled = 0; + + current->thread.gcs_el0_mode = enabled; + + /* + * We let userspace set GCSPR_EL0 to anything here, we will + * validate later in gcs_restore_signal(). + */ + current->thread.gcspr_el0 = gcspr; + write_sysreg_s(current->thread.gcspr_el0, SYS_GCSPR_EL0); + + return 0; +} + +#else /* ! CONFIG_ARM64_GCS */ + +/* Turn any non-optimised out attempts to use these into a link error: */ +extern int preserve_gcs_context(void __user *ctx); +extern int restore_gcs_context(struct user_ctxs *user); + +#endif /* ! CONFIG_ARM64_GCS */ + static int parse_user_sigframe(struct user_ctxs *user, struct rt_sigframe __user *sf) { @@ -653,6 +733,7 @@ static int parse_user_sigframe(struct user_ctxs *user, user->za = NULL; user->zt = NULL; user->fpmr = NULL; + user->gcs = NULL; if (!IS_ALIGNED((unsigned long)base, 16)) goto invalid; @@ -758,6 +839,17 @@ static int parse_user_sigframe(struct user_ctxs *user, user->fpmr_size = size; break; + case GCS_MAGIC: + if (!system_supports_gcs()) + goto invalid; + + if (user->gcs) + goto invalid; + + user->gcs = (struct gcs_context __user *)head; + user->gcs_size = size; + break; + case EXTRA_MAGIC: if (have_extra_context) goto invalid; @@ -877,6 +969,9 @@ static int restore_sigframe(struct pt_regs *regs, err = restore_fpsimd_context(&user); } + if (err == 0 && system_supports_gcs() && user.gcs) + err = restore_gcs_context(&user); + if (err == 0 && system_supports_tpidr2() && user.tpidr2) err = restore_tpidr2_context(&user); @@ -999,6 +1094,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, return err; } + if (system_supports_gcs()) { + err = sigframe_alloc(user, &user->gcs_offset, + sizeof(struct gcs_context)); + if (err) + return err; + } + if (system_supports_sve() || system_supports_sme()) { unsigned int vq = 0; @@ -1099,6 +1201,12 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user, __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); } + if (system_supports_gcs() && err == 0 && user->gcs_offset) { + struct gcs_context __user *gcs_ctx = + apply_user_offset(user, user->gcs_offset); + err |= preserve_gcs_context(gcs_ctx); + } + /* Scalable Vector Extension state (including streaming), if present */ if ((system_supports_sve() || system_supports_sme()) && err == 0 && user->sve_offset) {