From patchwork Sun Jul 16 21:51:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 120939 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp791737vqt; Sun, 16 Jul 2023 15:05:05 -0700 (PDT) X-Google-Smtp-Source: APBJJlGaP89H5gLLI2C9NwSttKq2/EUttB2VYNabrUIiaHjv4VAoTPalLKiqW1787er8gLDKEfhw X-Received: by 2002:a05:6a20:841a:b0:132:ff57:7fab with SMTP id c26-20020a056a20841a00b00132ff577fabmr13693903pzd.2.1689545105248; Sun, 16 Jul 2023 15:05:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689545105; cv=none; d=google.com; s=arc-20160816; b=HXpHdTSUWPKsZpo0yU3Wbnn0/F5NQ68xnvQ+1Gyu7otCP/8EMRCnV7t/h8QJotVLGv z0pMyFWiWhPJQO3IYFTuo5pLzAw4DlG+BCAP6Ic8742YvzhghjcI60NjoHO3ktoFYUzY fsaJrfhSZk7SBV2SR9pRpopvS/ph+0cBxoMYy+HlwKkUr9E0NIh8krhjzN1R2uaDFSN2 Y7FCsR32jPHdQwpCwJYbKcQOVJMZSMx19fGsi3mtWKXVFjJaSkW78u0SEPaOKVFHDHBV cWehDGuSaC3K5tfXORmBUw7iiQ9nVMTXCkKtbXpU3GxFre9ThhUhSm9YBbsucXd54kFa 4Xew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=Hoij89FgHlSln2qbJnF8Kw1b0bB5hfBrEMirwwZ3bdo=; fh=EdAFSmIgUzZTC6WCy4Jg1wBZ0/m6m2d/OjiRUJ3BsTI=; b=UugENgaTrZIOT9BYjOFaYc7xCTOSc8niJHvi4LvrObGxEeixOR1h34aqmxH1jVrzkT zQafdluCOHd1+INDA+B2OoCyBluBUWVVAEOCb7cGoBx5gJ2zWTGWCInsFw8SDb0eHBJ0 bvEIr0V9PXJ9R17cgXG9kKl2aj4ivqmKby/lRqT1JjZljUiDEdCCv7ktpP3vBf5VQeCy ZeAXKSJ4i9MfJAUFbSF6C32o2SJmp8QQIiSkWTadjxgqx5O/miV5PPcX4MXqjRL13qfP fNdVRUvxKzh05/zCI6kKqLXiy3J649dnerJUSkRIXgRmBS/hrOo4N6hb1BCXuH9Je/nn ob/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="uR2B/hb5"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x15-20020a63fe4f000000b005348885119asi10713381pgj.523.2023.07.16.15.04.49; Sun, 16 Jul 2023 15:05:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="uR2B/hb5"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233200AbjGPV7c (ORCPT + 99 others); Sun, 16 Jul 2023 17:59:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231263AbjGPV6h (ORCPT ); Sun, 16 Jul 2023 17:58:37 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF538423C; Sun, 16 Jul 2023 14:56:24 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8803760EEA; Sun, 16 Jul 2023 21:55:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3AFCBC43391; Sun, 16 Jul 2023 21:55:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1689544521; bh=0tWa6clX9JCLVAZLmK0c47eeS2V3fEjvfHYYtUy53CI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uR2B/hb5xMaeh2V17pUEhLNgvFKUy+QXEMdvrraqQYL9WYYLYK8JgSR/PEnt0Ruoq d2UFUUU4YatQh8P8TtewRPN8WzWQ1jQhxfZDqDYT9F5muRo1Vf5I797vGJ8ZD825rH xAm1WbwC/89ioYzvN/ngofllxRFMR2u+zzY/LDVPh6j6rc9659eEIzdzBdK30rnMSe XnImRbFsL6nTKViFcFerDgj2NJ861TSi/IeifhlJfE6Hi+FKYG1mft7tP2JmJfb5zI VPGQLjk2JlwYfOwuLblDUDXavXuRloXNClTIfojJQ3/MPhNCBfLD7Gs6mlVrM+6y6z 2t1K/TMTtL24g== From: Mark Brown Date: Sun, 16 Jul 2023 22:51:20 +0100 Subject: [PATCH 24/35] arm64/signal: Expose GCS state in signal frames MIME-Version: 1.0 Message-Id: <20230716-arm64-gcs-v1-24-bf567f93bba6@kernel.org> References: <20230716-arm64-gcs-v1-0-bf567f93bba6@kernel.org> In-Reply-To: <20230716-arm64-gcs-v1-0-bf567f93bba6@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 , Kees Cook , Shuah Khan , "Rick P. Edgecombe" , Deepak Gupta , Ard Biesheuvel , Szabolcs Nagy Cc: "H.J. Lu" , Paul Walmsley , Palmer Dabbelt , Albert Ou , 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.13-dev-099c9 X-Developer-Signature: v=1; a=openpgp-sha256; l=6047; i=broonie@kernel.org; h=from:subject:message-id; bh=0tWa6clX9JCLVAZLmK0c47eeS2V3fEjvfHYYtUy53CI=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBktGaiqEP/1t7St0+8Rv67UUUoUPQi6wMzzlC/PBSI Qqbg6k+JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZLRmogAKCRAk1otyXVSH0AtbB/ 9/pVA7++KnWfyO2DMPgqEfSb1NgHGU+bL0q7auMzFHTxMaTFqDF30zmebRfg8biQbdPtwoVAcbte/o Xh2j7B2pmNZrxbQtJO563zMh8PzeXCDRvYquYN4dR8MPZDgtgF8hknjx27aCwteI/0N2EO0AtcUA/X B+9LIyP5eopYZKx0ieNK+N//T1+VaboLWX8NdldfhhxrXF128z1MFvbBu1tMB6rY9s64DLcBcqUl/f X2gKf5hMaIALnGjqj4RXSq2F1nh+ngXFvVT5c2V4dcMU5HjfJkyWE7HS3/4GUFsY5XJoL5O9TNB5EJ JqhnaaeTaey/rtT2pN1T0kaa0PDU5G X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771616448100991319 X-GMAIL-MSGID: 1771616448100991319 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. Signed-off-by: Mark Brown --- arch/arm64/include/uapi/asm/sigcontext.h | 9 +++ arch/arm64/kernel/signal.c | 106 +++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h index f23c1dc3f002..7b66d245f2d2 100644 --- a/arch/arm64/include/uapi/asm/sigcontext.h +++ b/arch/arm64/include/uapi/asm/sigcontext.h @@ -168,6 +168,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 922b694fa0aa..83b464774cc0 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -87,6 +87,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; @@ -213,6 +214,8 @@ struct user_ctxs { u32 za_size; struct zt_context __user *zt; u32 zt_size; + struct gcs_context __user *gcs; + u32 gcs_size; }; static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) @@ -605,6 +608,81 @@ 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; + unsigned long gcspr = read_sysreg_s(SYS_GCSPR_EL0); + + /* + * We will add a cap token to the frame, include it in the + * GCSPR_EL0 we report to support stack switching via + * sigreturn. + */ + 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(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; + + /* Don't allow mode changes if the state has been locked */ + if ((current->thread.gcs_el0_mode & PR_SHADOW_STACK_LOCK) && + (current->thread.gcs_el0_mode != enabled)) + return -EINVAL; + + /* 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(). + */ + if (enabled & PR_SHADOW_STACK_ENABLE) + current->thread.gcspr_el0 = gcspr; + + 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) { @@ -621,6 +699,7 @@ static int parse_user_sigframe(struct user_ctxs *user, user->tpidr2 = NULL; user->za = NULL; user->zt = NULL; + user->gcs = NULL; if (!IS_ALIGNED((unsigned long)base, 16)) goto invalid; @@ -715,6 +794,17 @@ static int parse_user_sigframe(struct user_ctxs *user, user->zt_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; @@ -834,6 +924,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); @@ -952,6 +1045,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; @@ -1045,6 +1145,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) {