Received: by 2002:a05:7412:40d:b0:e2:908c:2ebd with SMTP id 13csp970384rdf; Wed, 22 Nov 2023 01:50:51 -0800 (PST) X-Google-Smtp-Source: AGHT+IH36JifmDdba2OWRCkKiXi1pAtkV28yYviCYgR/1K8JL/QlA3DJaUWpOkJlE0y28wAf5sDJ X-Received: by 2002:a05:6a00:2e97:b0:6cb:b7b7:c04c with SMTP id fd23-20020a056a002e9700b006cbb7b7c04cmr2316133pfb.12.1700646650844; Wed, 22 Nov 2023 01:50:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700646650; cv=none; d=google.com; s=arc-20160816; b=okcUHoGoLRdhQjRHXtAUd8BrG39oRxw1199dhZXxzfb8oPCJVrgm2U9W3yC5Ww0U7y LP73/1saYMkwBmsKM6gwxdl23UaMWzltYUOzokNOUm9MhsbdnleVIk186E+4TCPc/Eew 4PXqSL1hj5dQopc3183s18F8hoHfUhkUuojgto9+A+/HWaaSW/fdqrT7iOUQJLaEAIN/ Q3iW85XOd8B91263vNzmj770rvea5/pnc7dRt62/7IRgV+Xj5Hip8FBAUfiBjs0YyKeV aDZN8/tUR6KlC+rYaDMdgjwuPIbaxD8xiFFVOEZB51Q5dgGtf5AHcHSMNgsmbb42BQTc A5Xw== 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=kUdewf5TeEI+0UiBru498KG2Xvb/Y79qEfeBgcbbr8Y=; fh=DBA09WWQvC/ITzWF++5486U2O7bEUYFtf23DC3t+lKo=; b=ripkDcSnqDnQc3Jaq2uGMecnQPNEuR37YsxM+QCNuV7x6NNn75IfeU7LbzD0CH5Sp/ P3LKG2sGb9UcCElJgD51ZV99TVs9ec3ChYNipIH1pUE6ZIYP3NVojOeviFWB8s+YMvo2 KZ84qPwsOlKX/YPoNjGVmFGSaFa+zDyvyDwBwbz5L0yvKesmn32QMGkUAZJ9rTfn0JRT Z6Aolf2v3miB/3UxvsuHpzYPQ9NoNDqbW+bf77g+vXpYMO1oejkSm8Ho3lTzPm1iVLl0 8RNoOIOlLYMBcZcqzO8tHAxNVafpt8YLJ/lot4d8A4wI6HI5VuWIwxTIKjMdcBDJraCK TZAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=fKnWI82w; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from fry.vger.email (fry.vger.email. [2620:137:e000::3:8]) by mx.google.com with ESMTPS id q3-20020a056a00088300b00690c23d353asi12609854pfj.217.2023.11.22.01.50.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 01:50:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) client-ip=2620:137:e000::3:8; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=fKnWI82w; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 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 (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 99A318114EDB; Wed, 22 Nov 2023 01:49:46 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343780AbjKVJrc (ORCPT + 99 others); Wed, 22 Nov 2023 04:47:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343677AbjKVJrC (ORCPT ); Wed, 22 Nov 2023 04:47:02 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4236E1BFB for ; Wed, 22 Nov 2023 01:46:05 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0329AC433C9; Wed, 22 Nov 2023 09:45:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700646365; bh=OmIISmzme0R4+ZZhAdBzRBNSULPhQIu1MUcvbR0SztM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fKnWI82whn0XtZdXkPreiufY8bmPTbg/EhFaJf6C45E2ClZ6Xv2Zhoc7zg0gpoeKF brXoGKtIf3FI21RXrD8eJdIK6zfz+RvJtBibK7z+vO32SdMZw0j02YzIsdu8hFM69t k5vymDvbbKl+So6XOiIp2P1QrhzMC8diEO4SkAXIaJT+8b/RFjhLN8r5ZCcg8ozxox s3ru+GLB8ogDtroFfmq7CVBeUd55pS39+ibUDo4S0B5qsBQA+/XTrb4PzFS9Fcq58F qp9aZp7TCaLSSPxRfKqFXEemhscbubzUQLAS4H3J2bluTM/10+9X4yKtBNgwLSoSrv DEQ1osdYiB55g== From: Mark Brown Date: Wed, 22 Nov 2023 09:42:35 +0000 Subject: [PATCH v7 25/39] arm64/signal: Expose GCS state in signal frames MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20231122-arm64-gcs-v7-25-201c483bd775@kernel.org> References: <20231122-arm64-gcs-v7-0-201c483bd775@kernel.org> In-Reply-To: <20231122-arm64-gcs-v7-0-201c483bd775@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 , Florian Weimer , Christian Brauner , Thiago Jung Bauermann , 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-0438c X-Developer-Signature: v=1; a=openpgp-sha256; l=5977; i=broonie@kernel.org; h=from:subject:message-id; bh=OmIISmzme0R4+ZZhAdBzRBNSULPhQIu1MUcvbR0SztM=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBlXc0JHIYxL2UrB1tx7MSl6aRe7ZhUp/W9tRbtj gsL6qbyLg6JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZV3NCQAKCRAk1otyXVSH 0ItlB/97EBZweJSTZu8YX5Q8kOJfn4Y40tfmiBjCNZTMEzx/rxeR5DJ2uOALUItLzFzYwbr7xXt wlujHSBFfUEgz0xA9ogYtQECmdVjCE/1BTflw4B4J9zHnKw44v3FiJJJ4dLxTsH7E2+7s250vqt YKDkAz/HyNgSwVgfXy1zwlwovNqebe6+TENHaZPYUSn5eb5Yfm/ZX1+3AZQ35aDuvaAvvw5w0H9 EOdFTsc5+LnecbmGHXGtOqbJCISKXhAQDlvu6GklYlCoex0A0rt9J1XZJz3zxYcZvNiJUG45SgD WDFtGSLC6tHpbS+rC3B+RRoHZwnU+qXse8UzLqUFOyrB50aY X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-1.3 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Wed, 22 Nov 2023 01:49:47 -0800 (PST) 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 | 107 +++++++++++++++++++++++++++++++ 2 files changed, 116 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 b5dff91274fb..7ff775495f3e 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; @@ -214,6 +215,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) @@ -606,6 +609,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; + + /* + * 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(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) { @@ -622,6 +701,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; @@ -716,6 +796,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; @@ -835,6 +926,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); @@ -949,6 +1043,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; @@ -1042,6 +1143,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) { -- 2.39.2