From: Mark Brown <broonie@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Jonathan Corbet <corbet@lwn.net>,
Andrew Morton <akpm@linux-foundation.org>,
Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Arnd Bergmann <arnd@arndb.de>, Oleg Nesterov <oleg@redhat.com>,
Eric Biederman <ebiederm@xmission.com>,
Kees Cook <keescook@chromium.org>, Shuah Khan <shuah@kernel.org>,
"Rick P. Edgecombe" <rick.p.edgecombe@intel.com>,
Deepak Gupta <debug@rivosinc.com>,
Ard Biesheuvel <ardb@kernel.org>,
Szabolcs Nagy <Szabolcs.Nagy@arm.com>
Cc: "H.J. Lu" <hjl.tools@gmail.com>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
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 <broonie@kernel.org>
Subject: [PATCH 34/35] selftests/arm64: Add GCS signal tests
Date: Sun, 16 Jul 2023 22:51:30 +0100 [thread overview]
Message-ID: <20230716-arm64-gcs-v1-34-bf567f93bba6@kernel.org> (raw)
In-Reply-To: <20230716-arm64-gcs-v1-0-bf567f93bba6@kernel.org>
Do some testing of the signal handling for GCS, checking that a GCS
frame has the expected information in it and that the expected signals
are delivered with invalid operations.
Signed-off-by: Mark Brown <broonie@kernel.org>
---
tools/testing/selftests/arm64/signal/.gitignore | 1 +
.../selftests/arm64/signal/test_signals_utils.h | 10 +++
.../arm64/signal/testcases/gcs_exception_fault.c | 59 ++++++++++++++++
.../selftests/arm64/signal/testcases/gcs_frame.c | 78 ++++++++++++++++++++++
.../arm64/signal/testcases/gcs_write_fault.c | 67 +++++++++++++++++++
5 files changed, 215 insertions(+)
diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index 839e3a252629..26de12918890 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
mangle_*
fake_sigreturn_*
+gcs_*
sme_*
ssve_*
sve_*
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 1cea64986baa..d41f237db28d 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -6,6 +6,7 @@
#include <assert.h>
#include <stdio.h>
+#include <stdint.h>
#include <string.h>
#include "test_signals.h"
@@ -45,6 +46,15 @@ void test_result(struct tdescr *td);
_arg1; \
})
+static inline __attribute__((always_inline)) uint64_t get_gcspr_el0(void)
+{
+ uint64_t val;
+
+ asm volatile("mrs %0, S3_3_C2_C5_1" : "=r" (val));
+
+ return val;
+}
+
static inline bool feats_ok(struct tdescr *td)
{
if (td->feats_incompatible & td->feats_supported)
diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c
new file mode 100644
index 000000000000..532d533592a1
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+/* This should be includable from some standard header, but which? */
+#ifndef SEGV_CPERR
+#define SEGV_CPERR 10
+#endif
+
+static inline void gcsss1(uint64_t Xt)
+{
+ asm volatile (
+ "sys #3, C7, C7, #2, %0\n"
+ :
+ : "rZ" (Xt)
+ : "memory");
+}
+
+static int gcs_op_fault_trigger(struct tdescr *td)
+{
+ /*
+ * The slot below our current GCS should be in a valid GCS but
+ * must not have a valid cap in it.
+ */
+ gcsss1(get_gcspr_el0() - 8);
+
+ return 0;
+}
+
+static int gcs_op_fault_signal(struct tdescr *td, siginfo_t *si,
+ ucontext_t *uc)
+{
+ ASSERT_GOOD_CONTEXT(uc);
+
+ return 1;
+}
+
+struct tdescr tde = {
+ .name = "Invalid GCS operation",
+ .descr = "An invalid GCS operation generates the expected signal",
+ .feats_required = FEAT_GCS,
+ .timeout = 3,
+ .sig_ok = SIGSEGV,
+ .sig_ok_code = SEGV_CPERR,
+ .sanity_disabled = true,
+ .trigger = gcs_op_fault_trigger,
+ .run = gcs_op_fault_signal,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c b/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c
new file mode 100644
index 000000000000..d67cb26195a6
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+static union {
+ ucontext_t uc;
+ char buf[1024 * 64];
+} context;
+
+static int gcs_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+ size_t offset;
+ struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
+ struct gcs_context *gcs;
+ unsigned long expected, gcspr;
+ int ret;
+
+ ret = prctl(PR_GET_SHADOW_STACK_STATUS, &expected, 0, 0, 0);
+ if (ret != 0) {
+ fprintf(stderr, "Unable to query GCS status\n");
+ return 1;
+ }
+
+ /* We expect a cap to be added to the GCS in the signal frame */
+ gcspr = get_gcspr_el0();
+ gcspr -= 8;
+ fprintf(stderr, "Expecting GCSPR_EL0 %lx\n", gcspr);
+
+ if (!get_current_context(td, &context.uc, sizeof(context))) {
+ fprintf(stderr, "Failed getting context\n");
+ return 1;
+ }
+ fprintf(stderr, "Got context\n");
+
+ head = get_header(head, GCS_MAGIC, GET_BUF_RESV_SIZE(context),
+ &offset);
+ if (!head) {
+ fprintf(stderr, "No GCS context\n");
+ return 1;
+ }
+
+ gcs = (struct gcs_context *)head;
+
+ /* Basic size validation is done in get_current_context() */
+
+ if (gcs->features_enabled != expected) {
+ fprintf(stderr, "Features enabled %llx but expected %lx\n",
+ gcs->features_enabled, expected);
+ return 1;
+ }
+
+ if (gcs->gcspr != gcspr) {
+ fprintf(stderr, "Got GCSPR %llx but expected %lx\n",
+ gcs->gcspr, gcspr);
+ return 1;
+ }
+
+ fprintf(stderr, "GCS context validated\n");
+ td->pass = 1;
+
+ return 0;
+}
+
+struct tdescr tde = {
+ .name = "GCS basics",
+ .descr = "Validate a GCS signal context",
+ .feats_required = FEAT_GCS,
+ .timeout = 3,
+ .run = gcs_regs,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c
new file mode 100644
index 000000000000..126b1a294a29
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+static uint64_t *gcs_page;
+
+#ifndef __NR_map_shadow_stack
+#define __NR_map_shadow_stack 452
+#endif
+
+static bool alloc_gcs(struct tdescr *td)
+{
+ long page_size = sysconf(_SC_PAGE_SIZE);
+
+ gcs_page = (void *)syscall(__NR_map_shadow_stack, 0,
+ page_size, 0);
+ if (gcs_page == MAP_FAILED) {
+ fprintf(stderr, "Failed to map %ld byte GCS: %d\n",
+ page_size, errno);
+ return false;
+ }
+
+ return true;
+}
+
+static int gcs_write_fault_trigger(struct tdescr *td)
+{
+ /* Verify that the page is readable (ie, not completely unmapped) */
+ fprintf(stderr, "Read value 0x%lx\n", gcs_page[0]);
+
+ /* A regular write should trigger a fault */
+ gcs_page[0] = EINVAL;
+
+ return 0;
+}
+
+static int gcs_write_fault_signal(struct tdescr *td, siginfo_t *si,
+ ucontext_t *uc)
+{
+ ASSERT_GOOD_CONTEXT(uc);
+
+ return 1;
+}
+
+
+struct tdescr tde = {
+ .name = "GCS write fault",
+ .descr = "Normal writes to a GCS segfault",
+ .feats_required = FEAT_GCS,
+ .timeout = 3,
+ .sig_ok = SIGSEGV,
+ .sanity_disabled = true,
+ .init = alloc_gcs,
+ .trigger = gcs_write_fault_trigger,
+ .run = gcs_write_fault_signal,
+};
--
2.30.2
next prev parent reply other threads:[~2023-07-16 22:01 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-16 21:50 [PATCH 00/35] arm64/gcs: Provide support for GCS at EL0 Mark Brown
2023-07-16 21:50 ` [PATCH 01/35] prctl: arch-agnostic prctl for shadow stack Mark Brown
2023-07-18 17:45 ` Edgecombe, Rick P
2023-07-18 18:54 ` Mark Brown
2023-07-16 21:50 ` [PATCH 02/35] prctl: Add flag for shadow stack writeability and push/pop Mark Brown
2023-07-18 17:47 ` Edgecombe, Rick P
2023-07-18 19:10 ` Mark Brown
2023-07-16 21:50 ` [PATCH 03/35] arm64: Document boot requirements for Guarded Control Stacks Mark Brown
2023-07-16 21:51 ` [PATCH 04/35] arm64/gcs: Document the ABI " Mark Brown
2023-07-17 11:42 ` Jonathan Cameron
2023-07-19 11:44 ` Mike Rapoport
2023-07-19 13:25 ` Mark Brown
2023-07-19 14:04 ` Mike Rapoport
2023-07-16 21:51 ` [PATCH 05/35] arm64/sysreg: Add new system registers for GCS Mark Brown
2023-07-16 21:51 ` [PATCH 06/35] arm64/sysreg: Add definitions for architected GCS caps Mark Brown
2023-07-16 21:51 ` [PATCH 07/35] arm64/gcs: Add manual encodings of GCS instructions Mark Brown
2023-07-16 21:51 ` [PATCH 08/35] arm64/gcs: Provide copy_to_user_gcs() Mark Brown
2023-07-16 21:51 ` [PATCH 09/35] arm64/cpufeature: Runtime detection of Guarded Control Stack (GCS) Mark Brown
2023-07-16 21:51 ` [PATCH 10/35] arm64/mm: Allocate PIE slots for EL0 guarded control stack Mark Brown
2023-07-16 21:51 ` [PATCH 11/35] mm: Define VM_SHADOW_STACK for arm64 when we support GCS Mark Brown
2023-07-16 21:51 ` [PATCH 12/35] arm64/mm: Map pages for guarded control stack Mark Brown
2023-07-16 21:51 ` [PATCH 13/35] KVM: arm64: Manage GCS registers for guests Mark Brown
2023-07-16 21:51 ` [PATCH 14/35] arm64: Disable traps for GCS usage at EL0 and EL1 Mark Brown
2023-07-16 21:51 ` [PATCH 15/35] arm64/idreg: Add overrride for GCS Mark Brown
2023-07-16 21:51 ` [PATCH 16/35] arm64/hwcap: Add hwcap " Mark Brown
2023-07-16 21:51 ` [PATCH 17/35] arm64/traps: Handle GCS exceptions Mark Brown
2023-07-17 12:12 ` Jonathan Cameron
2023-07-16 21:51 ` [PATCH 18/35] arm64/mm: Handle GCS data aborts Mark Brown
2023-07-16 21:51 ` [PATCH 19/35] arm64/gcs: Context switch GCS registers for EL0 Mark Brown
2023-07-16 21:51 ` [PATCH 20/35] arm64/gcs: Allocate a new GCS for threads with GCS enabled Mark Brown
2023-07-16 21:51 ` [PATCH 21/35] arm64/gcs: Implement shadow stack prctl() interface Mark Brown
2023-07-18 17:51 ` Edgecombe, Rick P
2023-07-18 19:37 ` Mark Brown
2023-07-16 21:51 ` [PATCH 22/35] arm64/mm: Implement map_shadow_stack() Mark Brown
2023-07-18 9:10 ` Szabolcs Nagy
2023-07-18 13:55 ` Mark Brown
2023-07-18 15:49 ` Edgecombe, Rick P
2023-07-16 21:51 ` [PATCH 23/35] arm64/signal: Set up and restore the GCS context for signal handlers Mark Brown
2023-07-16 21:51 ` [PATCH 24/35] arm64/signal: Expose GCS state in signal frames Mark Brown
2023-07-16 21:51 ` [PATCH 25/35] arm64/ptrace: Expose GCS via ptrace and core files Mark Brown
2023-07-16 21:51 ` [PATCH 26/35] arm64: Add Kconfig for Guarded Control Stack (GCS) Mark Brown
2023-07-17 12:32 ` Jonathan Cameron
2023-07-16 21:51 ` [PATCH 27/35] kselftest/arm64: Verify the GCS hwcap Mark Brown
2023-07-16 21:51 ` [PATCH 28/35] kselftest/arm64: Add GCS as a detected feature in the signal tests Mark Brown
2023-07-16 21:51 ` [PATCH 29/35] kselftest/arm64: Add framework support for GCS to signal handling tests Mark Brown
2023-07-16 21:51 ` [PATCH 30/35] kselftest/arm64: Allow signals tests to specify an expected si_code Mark Brown
2023-07-16 21:51 ` [PATCH 31/35] kselftest/arm64: Always run signals tests with GCS enabled Mark Brown
2023-07-16 21:51 ` [PATCH 32/35] kselftest/arm64: Add very basic GCS test program Mark Brown
2023-07-16 21:51 ` [PATCH 33/35] kselftest/arm64: Add a GCS test program built with the system libc Mark Brown
2023-07-16 21:51 ` Mark Brown [this message]
2023-07-16 21:51 ` [PATCH 35/35] kselftest/arm64: Enable GCS for the FP stress tests Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230716-arm64-gcs-v1-34-bf567f93bba6@kernel.org \
--to=broonie@kernel.org \
--cc=Szabolcs.Nagy@arm.com \
--cc=akpm@linux-foundation.org \
--cc=aou@eecs.berkeley.edu \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=catalin.marinas@arm.com \
--cc=corbet@lwn.net \
--cc=debug@rivosinc.com \
--cc=ebiederm@xmission.com \
--cc=hjl.tools@gmail.com \
--cc=james.morse@arm.com \
--cc=keescook@chromium.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-riscv@lists.infradead.org \
--cc=maz@kernel.org \
--cc=oleg@redhat.com \
--cc=oliver.upton@linux.dev \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=rick.p.edgecombe@intel.com \
--cc=shuah@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).