From patchwork Sun Sep 21 13:21:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 120577 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 83F373858C66 for ; Sun, 21 Sep 2025 13:29:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 83F373858C66 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=LELg0SYP X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from tor.source.kernel.org (tor.source.kernel.org [IPv6:2600:3c04:e001:324:0:1991:8:25]) by sourceware.org (Postfix) with ESMTPS id CF38F3858D38 for ; Sun, 21 Sep 2025 13:25:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF38F3858D38 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CF38F3858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2600:3c04:e001:324:0:1991:8:25 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758461117; cv=none; b=IeIJh9MkHxd29b6a6y1dW4hne21yrwi8lzlUeuatfA9yx+VLMEvvklKHNWWtWjtqjOcqBxmQHLZct8uhjM+tn6rn2pSI0CWAO6AQbdA+05oiQUpWyc9B011vnEmWIPDgsoKLgoJY1WPlhQAUgwyMA0i0i1rV4Q6FXuq6PSJXOEg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758461117; c=relaxed/simple; bh=3qNbncmT90BPzEJJHaLs2HVYvULpPXQpoFHOrv1erBo=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=nCtkojVdNSD3RVYblKuwDhIGNhNpGvb3ZZxIeS9I9mKOcSynmj7+guTRTGf4Rq7FoxtPOBnu6RRupxGBGulU25baEq61VvoyPmYM0S8tn3LRgJL5Bx0P4+neP8BTybxTeetY8NAcfS9Pi/ekduoLdpPELSgvM42w5nqYgiLOeAU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CF38F3858D38 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id DBF19601D8; Sun, 21 Sep 2025 13:25:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A30C5C4CEE7; Sun, 21 Sep 2025 13:25:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1758461116; bh=3qNbncmT90BPzEJJHaLs2HVYvULpPXQpoFHOrv1erBo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LELg0SYPD4AnIDaWLAu7E81AxissJD842S6MuNVrG1RFsyPlCbT2Ikp9npXmc3zS4 APgEQFsJdTfs0Xem42FH0e6T3dJgH54tBLpN/ik4OSFIx7jhvw0+bAkA0q+0F/qnqX HJhYX9W8EDUlsAhRXwZF1zReLBAzJFY20RRI5QT5lLWfgMT38DO460BPTDJxvRN2oM TrKd3a4xu8iEx27dZsTRTL2odEMNjeldVunfaK42YRy9B5EGKlQ5WlYLYEJbxnH3pi HOGXJTKhxezIYbL4/T9/XBXpi8ThZFezQNA6ELX1McasStH9dEJiXfqPKnR0FYaV+b ECQXzrJFfGSGA== From: Mark Brown Date: Sun, 21 Sep 2025 14:21:35 +0100 Subject: [PATCH RFC 1/3] arm64/gcs: Support reuse of GCS for exited threads MIME-Version: 1.0 Message-Id: <20250921-arm64-gcs-exit-token-v1-1-45cf64e648d5@kernel.org> References: <20250921-arm64-gcs-exit-token-v1-0-45cf64e648d5@kernel.org> In-Reply-To: <20250921-arm64-gcs-exit-token-v1-0-45cf64e648d5@kernel.org> To: Catalin Marinas , Will Deacon , Christian Brauner , Adhemerval Zanella Netto , Shuah Khan Cc: Rick Edgecombe , Deepak Gupta , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy , Rich Felker , libc-alpha@sourceware.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Mark Brown X-Mailer: b4 0.15-dev-56183 X-Developer-Signature: v=1; a=openpgp-sha256; l=3650; i=broonie@kernel.org; h=from:subject:message-id; bh=3qNbncmT90BPzEJJHaLs2HVYvULpPXQpoFHOrv1erBo=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBoz/yzTrIqPApQZ0OfMN2FYRkkN4DO788ZCG5kU PVriIJMj4CJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCaM/8swAKCRAk1otyXVSH 0NHRB/4k36acdvvxC+SKXrPfjdAtzk1eCyj6iuuVO5LAxs4zrxRm6LUg9s4WJ07cPKb3T3N5ZrY F5vo4dKHb2F3EndagY7KQOHPaGje9/F1AJ8tt+1wyi1xjZD/F90TZjcft12SK3g4JIjmUu/2aLZ 07mEKDHO6Q0OUznBkfTP9bwgxcyart2aD/YrHd6zpBMMNlXmV9BzEmC6Bk+6EfbFT9QkQkDwYSX 30skzdWJVYBR8D9zfh/yAYi7fUnIIS7IfkenPzWzTedNh5i1QNfXBdHO4lu1B64ueOQPVRg+X9R NAWweJWKOPneipsyzmQWfGkPxQxVZqC7a/S/hJhXjqSlCy5J X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Currently when a thread with a userspace allocated stack exits it is not possible for the GCS that was in use by the thread to be reused since no stack switch token will be left on the stack, preventing use with clone3() or userspace stack switching. The only thing userspace can realistically do with the GCS is inspect it or unmap it which is not ideal. Enable reuse by modelling thread exit like pivoting in userspace with the stack pivot instructions, writing a stack switch token at the top entry of the GCS of the exiting thread. This allows userspace to switch back to the GCS in future, the use of the current stack location should work well with glibc's current behaviour of fully uwninding the stack of threads that exit cleanly. This patch is an RFC and should not be applied as-is. Currently the token will only be written for the current thread, but will be written regardless of the reason the thread is exiting. This version of the patch does not handle scheduling during exit() at all, the code is racy. The feature is gated behind a new GCS mode flag PR_SHADOW_STACK_EXIT_TOKEN to ensure that userspace that does not wish to use the tokens never has to see them. Signed-off-by: Mark Brown --- arch/arm64/include/asm/gcs.h | 3 ++- arch/arm64/mm/gcs.c | 25 ++++++++++++++++++++++++- include/uapi/linux/prctl.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h index b4bbec9382a1..1ec359d0ad51 100644 --- a/arch/arm64/include/asm/gcs.h +++ b/arch/arm64/include/asm/gcs.h @@ -52,7 +52,8 @@ static inline u64 gcsss2(void) } #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK \ - (PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH) + (PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | \ + PR_SHADOW_STACK_PUSH | PR_SHADOW_STACK_EXIT_TOKEN) #ifdef CONFIG_ARM64_GCS diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index fd1d5a6655de..4649c2b107a7 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,14 +199,37 @@ void gcs_set_el0_mode(struct task_struct *task) void gcs_free(struct task_struct *task) { + unsigned long __user *cap_ptr; + unsigned long cap_val; + int ret; + if (!system_supports_gcs()) return; if (!task->mm || task->mm != current->mm) return; - if (task->thread.gcs_base) + if (task->thread.gcs_base) { vm_munmap(task->thread.gcs_base, task->thread.gcs_size); + } else if (task == current && + task->thread.gcs_el0_mode & PR_SHADOW_STACK_EXIT_TOKEN) { + cap_ptr = (unsigned long __user *)read_sysreg_s(SYS_GCSPR_EL0); + cap_ptr--; + cap_val = GCS_CAP(cap_ptr); + + /* + * We can't do anything constructive if this fails, + * and the thread might be exiting due to being in a + * bad state anyway. + */ + put_user_gcs(cap_val, cap_ptr, &ret); + + /* + * Ensure the new cap is ordered before standard + * memory accesses to the same location. + */ + gcsb_dsync(); + } task->thread.gcspr_el0 = 0; task->thread.gcs_base = 0; diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index ed3aed264aeb..c3c37c39639f 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -352,6 +352,7 @@ struct prctl_mm_map { # define PR_SHADOW_STACK_ENABLE (1UL << 0) # define PR_SHADOW_STACK_WRITE (1UL << 1) # define PR_SHADOW_STACK_PUSH (1UL << 2) +# define PR_SHADOW_STACK_EXIT_TOKEN (1UL << 3) /* * Prevent further changes to the specified shadow stack From patchwork Sun Sep 21 13:21:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 120578 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7A0493858C30 for ; Sun, 21 Sep 2025 13:30:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7A0493858C30 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=Yc89g9/F X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from sea.source.kernel.org (sea.source.kernel.org [IPv6:2600:3c0a:e001:78e:0:1991:8:25]) by sourceware.org (Postfix) with ESMTPS id B1CD83858C78 for ; Sun, 21 Sep 2025 13:25:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B1CD83858C78 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B1CD83858C78 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2600:3c0a:e001:78e:0:1991:8:25 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758461120; cv=none; b=aVzdFEQ0eFnr1uC9zgdQ6BR6pjDj/tJWzje+MnUe6MhYdDUZcSGGw/bhEvlqLlxImv2UnYOnHamDQzrzp6TaYOv79U4M3l8/0CdYqPGHVZ3Z6YA6dPknE9suWm8Hw6lAl2P+5wUKHaKTCeJr4JfXCbJv4GpS6PS1Gd0ISSxKD0o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758461120; c=relaxed/simple; bh=FE4Staxl9+mwSZcKwcO0fto6nTUyhBcjpM/AKe7NNY8=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=OsFhD7r8IcZMxnM4Kb/N8a4dU/DU/YP7EnwvY8tc+DmIym3maUiZ5LQoTtX1xFndDL2AoxhMrcHzia6X9j9SbSJI3yy3DmF/UjJd9u2Giau02ZD+StJgDZOIVJFvPrtoFyk37Ong2VuIdt90CNNXhpq3F6FGDYhTIq1OQ9S6xdo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B1CD83858C78 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 0A29644DC3; Sun, 21 Sep 2025 13:25:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 029B7C4CEF0; Sun, 21 Sep 2025 13:25:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1758461119; bh=FE4Staxl9+mwSZcKwcO0fto6nTUyhBcjpM/AKe7NNY8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Yc89g9/F/laADXDu6ZyJb9kVjEtwNioPYXSRgxQXgZdPXrB4bbnYsLysHu5P/TAnp Kf1WdAGYFzTWs0JoLAxWrOL3griTN3JXT5sk/SK8n8Diuuwwkp/YTiogBod9aAwlDQ sjZ0NLixO9nACX4MxgOLjbNxFSYOvT44EE8ZfHoS08+T3BYCnHvX2dD1qqR1hqQ826 7cqHkPMvmeJfMfgmT1gcUmWixe85nSmgHE043GkTbJkbTVJk2i1x2rAN8RBUfmc2cq KWj1yheucpElKXGmqcA6i1NDumLxYwZXXYC7wPD/PHUL6dAYd2ESPV4dgMVCa2YZ1y 0eALsiHzHkV5Q== From: Mark Brown Date: Sun, 21 Sep 2025 14:21:36 +0100 Subject: [PATCH RFC 2/3] kselftest/arm64: Validate PR_SHADOW_STACK_EXIT_TOKEN in basic-gcs MIME-Version: 1.0 Message-Id: <20250921-arm64-gcs-exit-token-v1-2-45cf64e648d5@kernel.org> References: <20250921-arm64-gcs-exit-token-v1-0-45cf64e648d5@kernel.org> In-Reply-To: <20250921-arm64-gcs-exit-token-v1-0-45cf64e648d5@kernel.org> To: Catalin Marinas , Will Deacon , Christian Brauner , Adhemerval Zanella Netto , Shuah Khan Cc: Rick Edgecombe , Deepak Gupta , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy , Rich Felker , libc-alpha@sourceware.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Mark Brown X-Mailer: b4 0.15-dev-56183 X-Developer-Signature: v=1; a=openpgp-sha256; l=4482; i=broonie@kernel.org; h=from:subject:message-id; bh=FE4Staxl9+mwSZcKwcO0fto6nTUyhBcjpM/AKe7NNY8=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBoz/y0qv/Jyaej/JiKd4zy1N2rJ1bK2njRN45w9 EPbCK0jLlWJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCaM/8tAAKCRAk1otyXVSH 0KuRB/0bDm/ebdy8GZSxWh/fi1nPlICB1XII9YWAt+iA7wyVCD0CLW5vjcJPBAlk/BPRamycpdx 1/QlWc2HK7SLE/sM87DFGj3EEJneinoMRX3J3IdlgyopEbv1JBrkDyhm1P3Rwo9vk7ZGcwG3+sb OMVM7iTx1aNXZe4/ODOfo4LJb4fV73L4LAblIqhiO/3BljLKG67blpfF1SzkSfLqGz1ZlG0r1f7 CImcAMlZMzIXqCs1ADT/DegqlmLkWNGspPxK8hfy+F7rOJ3HCf5fl2ae97V/pxX7nmXkvTadfWO oyJ01dPgAhj2tIKe3nFNVx8Lrr71bNo3wDIqKekFGTMPEOZc X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Add a simple test which validates that exit tokens can be written to the GCS of exiting threads, in basic-gcs since this functionality is expected to be used by libcs. We should add further tests which validate the option being absent. Signed-off-by: Mark Brown --- tools/testing/selftests/arm64/gcs/basic-gcs.c | 121 ++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/tools/testing/selftests/arm64/gcs/basic-gcs.c b/tools/testing/selftests/arm64/gcs/basic-gcs.c index 54f9c888249d..5515a5425186 100644 --- a/tools/testing/selftests/arm64/gcs/basic-gcs.c +++ b/tools/testing/selftests/arm64/gcs/basic-gcs.c @@ -360,6 +360,126 @@ static bool test_vfork(void) return pass; } +/* We can reuse a shadow stack with an exit token */ +static bool test_exit_token(void) +{ + struct clone_args clone_args; + int ret, status; + static bool pass = true; /* These will be used in the thread */ + static uint64_t expected_cap; + static int elem; + static uint64_t *buf; + + /* Ensure we've got exit tokens enabled here */ + ret = my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_EXIT_TOKEN, + 0, 0, 0); + if (ret != 0) + ksft_exit_fail_msg("Failed to enable exit token: %d\n", ret); + + buf = (void *)my_syscall3(__NR_map_shadow_stack, 0, page_size, + SHADOW_STACK_SET_TOKEN); + if (buf == MAP_FAILED) { + ksft_print_msg("Failed to map %lu byte GCS: %d\n", + page_size, errno); + return false; + } + ksft_print_msg("Mapped GCS at %p-%p\n", buf, + (void *)((uint64_t)buf + page_size)); + + /* We should have a cap token */ + elem = (page_size / sizeof(uint64_t)) - 1; + expected_cap = ((uint64_t)buf + page_size - 8); + expected_cap &= GCS_CAP_ADDR_MASK; + expected_cap |= GCS_CAP_VALID_TOKEN; + if (buf[elem] != expected_cap) { + ksft_print_msg("Cap entry is 0x%llx not 0x%llx\n", + buf[elem], expected_cap); + pass = false; + } + ksft_print_msg("cap token is 0x%llx\n", buf[elem]); + + memset(&clone_args, 0, sizeof(clone_args)); + clone_args.exit_signal = SIGCHLD; + clone_args.flags = CLONE_VM; + clone_args.shstk_token = (uint64_t)&(buf[elem]); + clone_args.stack = (uint64_t)malloc(page_size); + clone_args.stack_size = page_size; + + if (!clone_args.stack) { + ksft_print_msg("Failed to allocate stack\n"); + pass = false; + } + + /* Don't try to clone if we're failing, we might hang */ + if (!pass) + goto out; + + /* There is no wrapper for clone3() in nolibc (or glibc) */ + ret = my_syscall2(__NR_clone3, &clone_args, sizeof(clone_args)); + if (ret == -1) { + ksft_print_msg("clone3() failed: %d\n", errno); + pass = false; + goto out; + } + + if (ret == 0) { + /* In the child, make sure the token is gone */ + if (buf[elem]) { + ksft_print_msg("GCS token was not consumed: %llx\n", + buf[elem]); + pass = false; + } + + /* Make sure we're using the right stack */ + if ((uint64_t)get_gcspr() != (uint64_t)&buf[elem + 1]) { + ksft_print_msg("Child GCSPR_EL0 is %llx not %llx\n", + (uint64_t)get_gcspr(), + (uint64_t)&buf[elem + 1]); + pass = false; + } + + /* We want to exit with *exactly* the same GCS pointer */ + my_syscall1(__NR_exit, 0); + } + + ksft_print_msg("Waiting for child %d\n", ret); + + ret = waitpid(ret, &status, 0); + if (ret == -1) { + ksft_print_msg("Failed to wait for child: %d\n", + errno); + pass = false; + goto out; + } + + if (!WIFEXITED(status)) { + ksft_print_msg("Child exited due to signal %d\n", + WTERMSIG(status)); + pass = false; + } else { + if (WEXITSTATUS(status)) { + ksft_print_msg("Child exited with status %d\n", + WEXITSTATUS(status)); + pass = false; + } + } + + /* The token should have been restored */ + if (buf[elem] == expected_cap) { + ksft_print_msg("Cap entry restored\n"); + } else { + ksft_print_msg("Cap entry is 0x%llx not 0x%llx\n", + buf[elem], expected_cap); + pass = false; + } + +out: + free((void*)clone_args.stack); + munmap(buf, page_size); + return pass; +} + typedef bool (*gcs_test)(void); static struct { @@ -377,6 +497,7 @@ static struct { { "map_guarded_stack", map_guarded_stack }, { "fork", test_fork }, { "vfork", test_vfork }, + { "exit_token", test_exit_token }, }; int main(void) From patchwork Sun Sep 21 13:21:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 120576 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3FB733858C2D for ; Sun, 21 Sep 2025 13:27:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3FB733858C2D Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=QotlogBe X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31]) by sourceware.org (Postfix) with ESMTPS id 0C0483858408 for ; Sun, 21 Sep 2025 13:25:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0C0483858408 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0C0483858408 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=172.234.252.31 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758461124; cv=none; b=rAk1q8SEJobaYn4z88nvvz6AbU/91ZMKGxFysfrPQ2kN+a2bRAe2z6v/kQ+5B/oRu3fNMms1rbCU6X/gfWVsQT9Q7RprDjZLvqhqbcc0AlDD8ScjKZQouKF9p+2f+ru37I0AnPi9Vfz/xEA1dKqWkc98u1t2mr9OTw1lPm9+nkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758461124; c=relaxed/simple; bh=s+wftv/lLO/HEynUJMSqPwVgj4JeieBXIF19Z/tEeQI=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=DkAJk2lb+jQrZEdrAbV4XV17Lz8BhW/VQ2wD6MS31FnCAioyQCrDok5hbADq4jeu54Le12qjx3lM/bd17jN0ubdE6Pbv+eSfPEjwkaEyfevP/1rQLIa3SBd4/x0Y/BUuhpiz0PKEXYW2B4cJCloOBY+/zRlH5kNuKnLBmXJ/keM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0C0483858408 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 5FD9A441E0; Sun, 21 Sep 2025 13:25:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 546BBC4CEE7; Sun, 21 Sep 2025 13:25:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1758461123; bh=s+wftv/lLO/HEynUJMSqPwVgj4JeieBXIF19Z/tEeQI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QotlogBeC2DAkXLKYM0i4uU3XzeMVEO/V05JQ1xVW2aGY2/WMgdclV3WFKlibnVf6 FHDIj6Rkyw3fg/XthzquvfDs24o4marNjzhn7BG7uEO8iUQeGo57iizhxK5MeVzF5F AaRN3UuCvqRiV7NriPgrrdvkVuj3rDy8YWHlDY9+2+kAp+f4mSBThNfRKe8Uyb5W5H MTlWepoOOL9VamUbpmdOc91g6VCaFtXuUUNnNnRCFA7vbwTBS7RwyztWsEWsR9goBq JJPKgs4p8aFwmCPdL1YaFV1WmZAOK3lR/iO+NsJIH93EOeqBaUmMnGOzFZqLkEDPxG F5m4323sX2+Ug== From: Mark Brown Date: Sun, 21 Sep 2025 14:21:37 +0100 Subject: [PATCH RFC 3/3] kselftest/arm64: Add PR_SHADOW_STACK_EXIT_TOKEN to gcs-locking MIME-Version: 1.0 Message-Id: <20250921-arm64-gcs-exit-token-v1-3-45cf64e648d5@kernel.org> References: <20250921-arm64-gcs-exit-token-v1-0-45cf64e648d5@kernel.org> In-Reply-To: <20250921-arm64-gcs-exit-token-v1-0-45cf64e648d5@kernel.org> To: Catalin Marinas , Will Deacon , Christian Brauner , Adhemerval Zanella Netto , Shuah Khan Cc: Rick Edgecombe , Deepak Gupta , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy , Rich Felker , libc-alpha@sourceware.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Mark Brown X-Mailer: b4 0.15-dev-56183 X-Developer-Signature: v=1; a=openpgp-sha256; l=2141; i=broonie@kernel.org; h=from:subject:message-id; bh=s+wftv/lLO/HEynUJMSqPwVgj4JeieBXIF19Z/tEeQI=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBoz/y1M7sHRQ/XGEyodNfOn9vWhZ9M8eyHg8M9M BlLxc+D3NOJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCaM/8tQAKCRAk1otyXVSH 0FfoCACGdjQtSrOTxShjPpSqtxWnJCMmalNBZUZgxX4Lde+8F29/Ie6usgMTZi7LgEcIB6IuMfp c3SsNw4PVX6daOoVIAaeyG1tuRrhnVM49m3Vs1IA7Kg1j0M95+Ptn1cUiFhB0Dja2g3LVHGhGCN rbhq1SDo8z0iPIfbAckPabd30aF2b4vx79KQazn7CycchrCtVhXH2/nBP+cGjNKkJ1W0ebxMYOo XNC94IgXeu9Eyivm5R6S3uNF+NWuK8vR8wXlwd6pyK8FtNpq+UJqWZxdkki2L7HNPNlNhHRJEPf NKwMfkP9asW7LwJldu8/izVUaCnDq1nDZr1bhR9HA55s3WTy X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org We have added PR_SHADOW_STACK_EXIT_TOKEN, ensure that locking works as expected for it. Signed-off-by: Mark Brown --- tools/testing/selftests/arm64/gcs/gcs-locking.c | 23 +++++++++++++++++++++++ tools/testing/selftests/arm64/gcs/gcs-util.h | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/gcs/gcs-locking.c b/tools/testing/selftests/arm64/gcs/gcs-locking.c index 989f75a491b7..0e8928096918 100644 --- a/tools/testing/selftests/arm64/gcs/gcs-locking.c +++ b/tools/testing/selftests/arm64/gcs/gcs-locking.c @@ -77,6 +77,29 @@ FIXTURE_VARIANT_ADD(valid_modes, enable_write_push) PR_SHADOW_STACK_PUSH, }; +FIXTURE_VARIANT_ADD(valid_modes, enable_token) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_EXIT_TOKEN, +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable_write_exit) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | + PR_SHADOW_STACK_EXIT_TOKEN, +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable_push_exit) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH | + PR_SHADOW_STACK_EXIT_TOKEN, +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable_write_push_exit) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | + PR_SHADOW_STACK_PUSH | PR_SHADOW_STACK_EXIT_TOKEN, +}; + FIXTURE_SETUP(valid_modes) { } diff --git a/tools/testing/selftests/arm64/gcs/gcs-util.h b/tools/testing/selftests/arm64/gcs/gcs-util.h index c99a6b39ac14..1abc9d122ac1 100644 --- a/tools/testing/selftests/arm64/gcs/gcs-util.h +++ b/tools/testing/selftests/arm64/gcs/gcs-util.h @@ -36,7 +36,8 @@ struct user_gcs { # define PR_SHADOW_STACK_PUSH (1UL << 2) #define PR_SHADOW_STACK_ALL_MODES \ - PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH + PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | \ + PR_SHADOW_STACK_PUSH | PR_SHADOW_STACK_EXIT_TOKEN #define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ #define SHADOW_STACK_SET_MARKER (1ULL << 1) /* Set up a top of stack merker in the shadow stack */