From patchwork Tue Oct 1 22:59:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13818926 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 F0AA3CF3189 for ; Tue, 1 Oct 2024 23:04:52 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 85EF3680034; Tue, 1 Oct 2024 19:04:52 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 80F8768002B; Tue, 1 Oct 2024 19:04:52 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6616B680034; Tue, 1 Oct 2024 19:04:52 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 44EC068002B for ; Tue, 1 Oct 2024 19:04:52 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 07FE81210F7 for ; Tue, 1 Oct 2024 23:04:52 +0000 (UTC) X-FDA: 82626565224.26.89DD643 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf25.hostedemail.com (Postfix) with ESMTP id 35CE5A000B for ; Tue, 1 Oct 2024 23:04:50 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=BwIW27cY; spf=pass (imf25.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1727823825; a=rsa-sha256; cv=none; b=jj2kuLjumxpBw8eCakc6nh3wV2TJjh4m/l+igVh8q7qgRMBTJk7A+nUTrpngkPTkDnWUMP 0vSGIoYQ//waGiYITOJtl409haHpPkb/vvkDvwzt8DFVHAPwoASrFWNlm0v04OrcDTU519 ol3+ZqIw+UuPl4oWKoBIP0xCEPNy4MU= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=BwIW27cY; spf=pass (imf25.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1727823825; 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=4dc87HmpeS9cE1L9M4FvapEXtqDd8oHbPk8aV/GQpko=; b=MgIA+O/xNdHkB/gVfAhSb/JFcSwMAnmUuOOO0wE63ae/VQ18fSD6c1+2QjlKF7ycRX4fL1 cF53Tzi8Mr3kyYTf+MM/jicRRvogjRbBETnFb120wJpcp47RFU5E7vhtZ42aGx/QHEXgOC 6vgQekgH+4i8dauiOt14ry39A9d/LNA= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 3F7925C0339; Tue, 1 Oct 2024 23:04:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C8BA5C4CEC6; Tue, 1 Oct 2024 23:04:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727823889; bh=iheYVdOI1mRov1x2wnyFTq0nLuVXvcgzNFY1vvTX4L4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BwIW27cYksAnySxigWOYt0SrEnqSg8DQYIaOnWhOA0RmnhGPkZNsPdLvpGjXLHoFy x9mBOmkAgbznrCwLJIwQXwgbSpQgLgda83m7E8XTGR/hpwmO9+3OPAi1uU0TCEeGyM 9JiEyK/6y5TPZbGoIs2Q4X1QSD6nD+29VI2lTNHh20WKw6hGcZlOF91t4tyvyGGUud Er3KBwhnr6s/S5WpZBGIZsV6T9/+OZ8Q9UeC9TufeeP6UnCEheXFhvzHTC1pWfDdE7 blzYCs94us/bd2Nqjy+3llEwkSsm9Kk0bQaxm2WUjd4zYSbW2gZTb+pX3qgl8J3TvX ZINL9rlEvPKdg== From: Mark Brown Date: Tue, 01 Oct 2024 23:59:05 +0100 Subject: [PATCH v13 26/40] arm64/signal: Expose GCS state in signal frames MIME-Version: 1.0 Message-Id: <20241001-arm64-gcs-v13-26-222b78d87eee@kernel.org> References: <20241001-arm64-gcs-v13-0-222b78d87eee@kernel.org> In-Reply-To: <20241001-arm64-gcs-v13-0-222b78d87eee@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 , David Spickett , Yury Khrustalev , Wilco Dijkstra , 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.15-dev-99b12 X-Developer-Signature: v=1; a=openpgp-sha256; l=6331; i=broonie@kernel.org; h=from:subject:message-id; bh=iheYVdOI1mRov1x2wnyFTq0nLuVXvcgzNFY1vvTX4L4=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBm/H7Yz8d8MeWJ1s7RbiNfQuHzARatODnl4idncq8R cuNHIXOJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZvx+2AAKCRAk1otyXVSH0IwMB/ 9jNDjhhihZZ4eg1B5HLLhXzEXv8N0aVlgGh/C0HpKuP1JRpb9vWvmXYmEb9b+OED6jwkbAaDTq34DO tIgwn8Hxp1xHgkhwqJPTA/ZlaSRZsLMpjQGYO50gNphK4ZTqB8UsmomfvnmqpiHRG2Tvn9yfF6ctdn 6jCSM3nAAnS9z/iZyVIRdD+DJ6uqNygJh5d+zzcrtYXSjxfHHUH6WFm4VP9CsuiY/zjMTz3cQCR+GD Dkyz+qG+3r8mAsYatUuQH1MZvCZPtuexKj1rWX0DbluY1QzNURLAZ+Wzhk6r8UfrQ2C7Dpaj+1j8fk vzEPmC/B62LJ0D69GBKu8xUJsBBlQj X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Stat-Signature: 6q8xkedhe7e5ua9rs6es8siiuj1h741i X-Rspamd-Queue-Id: 35CE5A000B X-Rspam-User: X-Rspamd-Server: rspam10 X-HE-Tag: 1727823890-418095 X-HE-Meta: U2FsdGVkX1+xvHXQgNnll5ggPTvatCgNwKSW/5Q+Odc7UImyrW1IUFEq3bE14TAUZgQHL434YLHsK0pbZyjPxCI9BPmsC7iJ1DMZTrKea9bDrK5r29EonVaOMBcBgHqvyW6TioDGSL3La2dKI6lJFY+eFQMEW4hibpBzlFcaUJNpCNgyN+aagfmFqjYF4EXnBdUFjbQpy2hT7tVfN1+/cLdMZdV2N5IX1Uk0Oe6PMuwy3ukNSyjqjlYyTqYx6kRhRKswSj9ko5iPAJAxqjq8N0BUEzLL85b25B4iHY6JNWEQ0PMPcj+ROdJ/Sn6YFSGOoax6R6M31UQLBn7sZnv5teZdxm/+0PLrggyhZuC+7DCSo21nQADzxqie8cgU5P0P0aBgQgNjIzfVNofLmZLFFpvMmYGHNzBAdEBebja2Y9o3/At2T4F8FbksCMaAf0B7unGy6E82rJTHut9zK4JeDkCIlmFNyrzJMyMrzWwdSM492T1YzvG/jDW00sNs3eFobmJNXBy4C7NHvPJ894spD7L7sY7MGDTIGMShQ1FQGMvRttrpLQb5azEDMYkp8t5nItzdSRBeK+27sxCQVhfANVzB1xLRRqQ/H1buGR/DF5AeCvQeuCuc2vA5eDJZXaZLnog+rl/5Jmy2YYVq2zFK6QJZoH2dNM2xiZmKAzCrfNkDP9nlKbIa4aIrT8HNqq85GYxgITtIuyQGVEKgxtRUZ1S/yKsEXbSP7ZwAgexacbXAXW8zp2WEufsP8B+ioAYNEKECarwrjf7IH2UX1rE+y93xZrEAVNyKou8ywYRy6gmMwagC3uiw0M3VPHZM8U72HCVJFCUyJp6jbq6XiRes5EJjyOSNIOXgAHvQfslijlfw8R+2zbIYPXqvWYaAwTdaFqtXXoPadm9RlYLkUquZor5o5smqx6AM6bL5Y5JkAGA4UaLolLqEq5x5TXW1mtkA7sKw5WimgoPtDYABGpJ ugrdh074 VV3foI2vyeS5Q9aub2OWljPMRVW9XNRGxWl2uZp75DDg4d9pGEIJKA+TehBYbIyFXHHbg5uHaK2QX7TMGDxe75q6eRHUzblvr8TMIAkM9TaNWaOEGw3r68OJ6MLCA2+RRmJYaVcJCLqmvxyVVerZjHxTqkX46bu6dFf7oeCSuTvJjK/BqwoX6UNsEbJlAhgfWR8bmWcZ7gZxOHCrQhelgeRrn/IHyigpVKSKB/sSQUAUJ/raK6+3CKyXrX0awLhuBMZY25BIbyFl121pJQYpSo3EskTHHjPzBKACQ1HlluTcz6nUC0uMAuYoJFcTEY6YyekXKms3CwG7fnTqSRwUR+1mngkpAOOG6TC2pxR3kCBiQmdp5EfPn3Juu9WBvaQ5MMqYJ+ibeqQ/IZYGyrwB8s8qnIBzApEjUP3Mv3jlC+rfrV/haqAk4LO6g2w== 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: Catalin Marinas Reviewed-by: Thiago Jung Bauermann Acked-by: Yury Khrustalev Signed-off-by: Mark Brown --- arch/arm64/include/uapi/asm/sigcontext.h | 9 +++ arch/arm64/kernel/signal.c | 109 +++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h index bb7af77a30a7..d42f7a92238b 100644 --- a/arch/arm64/include/uapi/asm/sigcontext.h +++ b/arch/arm64/include/uapi/asm/sigcontext.h @@ -183,6 +183,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 b5ab0e229a78..62d666278264 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -66,6 +66,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; @@ -198,6 +199,8 @@ struct user_ctxs { u32 fpmr_size; struct poe_context __user *poe; u32 poe_size; + struct gcs_context __user *gcs; + u32 gcs_size; }; static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) @@ -643,6 +646,82 @@ 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 = read_sysreg_s(SYS_GCSPR_EL0); + + /* + * If GCS is enabled we will add a cap token to the frame, + * include it in the GCSPR_EL0 we report to support stack + * switching via sigreturn if GCS is enabled. We do not allow + * enabling via sigreturn so the token is only relevant for + * threads with GCS enabled. + */ + 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(). + */ + write_sysreg_s(gcspr, 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) { @@ -661,6 +740,7 @@ static int parse_user_sigframe(struct user_ctxs *user, user->zt = NULL; user->fpmr = NULL; user->poe = NULL; + user->gcs = NULL; if (!IS_ALIGNED((unsigned long)base, 16)) goto invalid; @@ -777,6 +857,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; @@ -896,6 +987,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); @@ -1029,6 +1123,15 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, return err; } +#ifdef CONFIG_ARM64_GCS + if (system_supports_gcs() && (add_all || current->thread.gcspr_el0)) { + err = sigframe_alloc(user, &user->gcs_offset, + sizeof(struct gcs_context)); + if (err) + return err; + } +#endif + if (system_supports_sve() || system_supports_sme()) { unsigned int vq = 0; @@ -1136,6 +1239,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) {