From patchwork Mon Jul 31 13:43:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13334745 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 2FD22C001DF for ; Mon, 31 Jul 2023 13:53:16 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C7886280057; Mon, 31 Jul 2023 09:53:15 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C28A3280023; Mon, 31 Jul 2023 09:53:15 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B1836280057; Mon, 31 Jul 2023 09:53:15 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id A063B280023 for ; Mon, 31 Jul 2023 09:53:15 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 71F1180B3B for ; Mon, 31 Jul 2023 13:53:15 +0000 (UTC) X-FDA: 81072048750.26.8BD79E1 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf30.hostedemail.com (Postfix) with ESMTP id 5636D80012 for ; Mon, 31 Jul 2023 13:53:13 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oCYcF4qc; spf=pass (imf30.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 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=1690811593; 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=Tv3ZQTe1vq0gXi/ckLnsUDbjI3sqm8avbDnc9Ul9ahA=; b=0qtKO4jPTchxBHFFOmjj1z6PNZm8bD9eE9mT7I4eZn+tZelFAXsu3P/y0HzBlEIWFS2o/G 0QmP4RcX3WeczgsrXk3Dc8SSbg2ktY6Qw/CiYQl5hFF5M24R3jm110lYVXHSy9cqvyuqrI 1n/Omv3SzeSXpFBG6SFRr+zRntpURqE= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1690811593; a=rsa-sha256; cv=none; b=2+msGAx1EgNV6CDpmh4bKk8PuiI5Z7zqIRbEsUibPTGZ5s/C51kMeB5Blv6ksI6BVvo3Mc TVhuye5mm9WkXTPvmZHYONqQZtXhGI3Qc0/m4VhqBAK5vxkXtreeczFAQ4qqtjlRtwEHLf 1Ehn0lmlULZoL1wpFMKDrbESCSit9MA= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oCYcF4qc; spf=pass (imf30.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=none) header.from=kernel.org 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 8B5886115E; Mon, 31 Jul 2023 13:53:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45C50C433C9; Mon, 31 Jul 2023 13:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690811592; bh=KnBf3819XLYZd+1IcRnGIifcqO5I4WiAi+2WJjL5RP8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oCYcF4qcCW/kcOsq3hrnnR0SifSVnJItIU3l2Tp7ESdSZYmvCrsxPDRcNzid7TooF ZX0Z9IZZXjbe8GbrIU2pCqtjvrkUFHSMBNwgdqaxRUoZN+dc64l9TMYsRg8ADR78V1 viUEIIaKwW186ErFMdBFZnQfctS3YdCai73rEhPRciczpG9lGaW6mFZn1JoAV4wQqb /S/hPPXmHEIAPsPJMGnxJiqUkGH7iGYeue3UMs55PVEJIfhy5K1pt6si1ppb3Dw36N wbyDCdOhZIpDRLpEVWzdCEXndBHK8crlrb3nsGv5BwP3BSDHpPA7N+4TMZIxPJ54CN M9Aqiv25izMiQ== From: Mark Brown Date: Mon, 31 Jul 2023 14:43:32 +0100 Subject: [PATCH v3 23/36] arm64/signal: Expose GCS state in signal frames MIME-Version: 1.0 Message-Id: <20230731-arm64-gcs-v3-23-cddf9f980d98@kernel.org> References: <20230731-arm64-gcs-v3-0-cddf9f980d98@kernel.org> In-Reply-To: <20230731-arm64-gcs-v3-0-cddf9f980d98@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=5977; i=broonie@kernel.org; h=from:subject:message-id; bh=KnBf3819XLYZd+1IcRnGIifcqO5I4WiAi+2WJjL5RP8=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBkx7wmfIBFkN2niYmy8mVjiWaU54J+vhgsObWk0GYb 062RqJqJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZMe8JgAKCRAk1otyXVSH0M5UB/ 4us3Hv7/mq8oJ7CemwMMqxY+8U8Ycd/IcnLB7fHMp1EYS4OOcAq+ibq5SUjyCU4Yd6R7n/9AnXX8Um RP28au338A0EqSoxuXQ/Hp9NB8+HntNy7QTgZ/m/NsvXeIaqtg51rX7j5u/MYZanGILIuebzAXQF7w 5NBmE9320eckXzOyxWW4wr0OdEOTLUFJCGJe3+Xw+KYsIdvCjcVmLGhL0ThgWaDCZZlbOC6AW+owyQ MCtk2DGkcQRsic3Gw/k/Ak05L0XY6YbX9bPQedPBbLzmJSvqtfQ8hNc1kjDau7gHX1jY2vkOwDkRY6 p2BwW2otdDdWZk8h7RWHPwUEpq900V X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Stat-Signature: jdq77b67yzmb7iisjef7myh7kmj444zh X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 5636D80012 X-Rspam-User: X-HE-Tag: 1690811593-117028 X-HE-Meta: U2FsdGVkX18S84rLS0cBClXBYz9KOuvQTybGxme4MnHbSX9B89bqMKid+NJgDERy/waP+rly+XAWYBT3xvKK6wv37vTy2+z/0mBaV/xA58jZlkF/0S3U8vh9Q01GoHaaw8GfMgBXx2FsylHhy4PNjqZSivEnHnjynclv4wEmeRYOGU9SMShS4UjPcicK4L+dvRdDcXyCmUcDJVqTUFoF6qZF1E70h7l0IzYNuo4t7WGAMrTMbh8PYELEWlkVRazQsXV3ahNuT5a0Lkn9qGFV2DfjQmszC1D/wJLmlDMal58XXoLw+szwr2vUw2ylFrlef/UlxHpkDzpLjXvuaH95YxcOQHu/27dyDIfJIfaYvdW3v6XvZ7Q0GKNF5J2uc9mTLcDg9b5KmEkgj1XotTQOMH3St8RPzFbE/D7RaGkLuB9hTtI9eGErOX0ywzF0egu8EW4deTFIAgPPiuMf0c/KmwJJjWj8K/sU3zXz6qEYWGTNddx+uJPR2bEjs6lcAqKJqbcb+9fqX5if2gOJzJomKyM4wyU8hD5p1WJVmdemxZOwk1cLP+8T+3uBWIStwQ93W/yQEZlxi7ldsOu0GyhNP8lwt8lSuja1iEZTiXquwU4mDoUQROsYLJgonLukDH9B3UpdKVeN7xGJQ5Vn5gr4hiKDHwn8q5hY/jJ0ZVAcbF+I0Axbin52xhzTqag2YfPoUqvBTlJgREDfPKkiTuvHJorBQZDkJZy8JoTBNo4mHPR//HF3EwiuUPWTmoqk5Mzg6rxQd1WmziVd2oZEQm4jsjy+XrseVe9SrWnCPBs5yA+CGKLWsPwRHA69619bYN+Ti20pmdRzqufa4QHUsF39rNLlHthJZM91ixC6M/dzMOaZlckrs/jtBvG5lbw+vp7YfEYysJHltznWqdPyGaPHx+oQUQwytXHBRkm5lsz88Rpq2hHtl4wq6CfnzQsCEKVMbxe1lhXNx9JxNLbcioS p1kEChw5 b17VcQxWa44Tx635M5gLlJlftgXEG/M96RXd+bqAPQuxPyzAacj/YFEapud2sZ78fUHOKWQAmEFTOS6qHmBnHD7bHVu4R2ykGawxD7gDMdb3Ja804PKuwyO2HqytyvKu2W0gsgjacmbsp9IrHeMCGZYJ1HwBDy3OYAncnyBNmP46gNmUrINcXQPY8EdbgZAROGgdLg1iYcHZi1owBeHQGaZKXifW7m96RK86saWEfiuWW4dj1gGQ6TdfnJZ11bd18to+mVEErNcdkrEYhPJcdFrxnUuFXA/ZmfU3zaFh3NHKx4H80+9fIMFHsEb2Dd5I8pCBZpus+7yZmZrZy9ah9hfxO81puwjgHY7M7RD5o+BkxJOczfnvglsY2s3M3sOYLfywgOyATsXLSoYPDkkvLcXl1FBSAPm2NGuaf8wbU7Z1JvxU= 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: 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 1c31be0f373e..4cc0c7928cb3 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,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) { @@ -621,6 +700,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 +795,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 +925,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); @@ -948,6 +1042,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; @@ -1041,6 +1142,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) {