From mboxrd@z Thu Jan 1 00:00:00 1970 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 83ABDC001DE for ; Mon, 24 Jul 2023 12:50:36 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 24AE7900006; Mon, 24 Jul 2023 08:50:36 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1FB4B900002; Mon, 24 Jul 2023 08:50:36 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0C396900006; Mon, 24 Jul 2023 08:50:36 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 00388900002 for ; Mon, 24 Jul 2023 08:50:35 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id A5DBC80A33 for ; Mon, 24 Jul 2023 12:50:35 +0000 (UTC) X-FDA: 81046489230.16.7C83488 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf11.hostedemail.com (Postfix) with ESMTP id AA5E64001A for ; Mon, 24 Jul 2023 12:50:33 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=ZKj1YYEo; spf=pass (imf11.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=1690203033; 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=XJbY1bFU7w0cPaQF6eYkdTRefgro7AfSI1KvzwfLPNE=; b=SWKOTGTxWJdo4kw/uMwEtAA0Sd2O3qU1edmJpDs1f+SjbELo2EPRiKmwB/FBdi27LJkPXP 24TyJTOmtclY3tX+AgaDq1829cmASVefbrOQnjn+dC/nulw5z87JfcLh2o+kwl2M46Eq5L Xjb8WXAxxY8ErdOpiT62t4WB0c0LNoo= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1690203033; a=rsa-sha256; cv=none; b=BL2ezX8VopdyZN347kWOhhBjFWoS8dHqPFYjsfYAnl4QHhCJoN49k1FWJpiVN5GHyQlYU2 d2bMXCMjJ0NqowlY0xp/798B7frLEaT7y0MaFv1hKMvCvVTU7Exrw8p9w3mNaD+jWWG7E8 z06xiCDfGBxWamJ/aN/migTbGGddxhE= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=ZKj1YYEo; spf=pass (imf11.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 D9B376116A; Mon, 24 Jul 2023 12:50:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7659AC433CD; Mon, 24 Jul 2023 12:50:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690203032; bh=h9bKdgMYA3yorcV7MRrWgctU4KZ0wYlnm+mQUdEZpv0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZKj1YYEoVdPc8fiwTzf0w74FCo37vXYTSCnrdcJD2+UbhrpFbSFR2OWfYVVNrcUUO LW7wLjp8wvkzyXUHlaGFt0RHzK2JVuMIT0xeoytqKKSMvgzfHxCNoS7BKEv4om9gKj g7iikWD0MJilgs2FcZxhgLP3NanFBY47WDrLkrdNGLKoY0IrlB6I49P84S2zzTo/wo iavhCbwftdOujha/hl6W+Aqga6/uZKtKEx1DlSf0MNCeGXzB4xyh9OXmG9RqRdQ2Xn 03PGnCiQ3YhevMR1SJrsVraIp8HEHRY1ODwTEOD+ITWyEBMWXe2z7PmIk9OnMh62WG 1xwss/vOJgUQA== From: Mark Brown Date: Mon, 24 Jul 2023 13:46:20 +0100 Subject: [PATCH v2 33/35] kselftest/arm64: Add test coverage for GCS mode locking MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20230724-arm64-gcs-v2-33-dc2c1d44c2eb@kernel.org> References: <20230724-arm64-gcs-v2-0-dc2c1d44c2eb@kernel.org> In-Reply-To: <20230724-arm64-gcs-v2-0-dc2c1d44c2eb@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=7316; i=broonie@kernel.org; h=from:subject:message-id; bh=h9bKdgMYA3yorcV7MRrWgctU4KZ0wYlnm+mQUdEZpv0=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBkvnK6f0LijlTKL84z+30hoEFVoLTAGbO13aFzceqb oKvKnmSJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZL5yugAKCRAk1otyXVSH0FkAB/ 49tfu91qRtZp3kO9rWiQppU164eKhqP9Ay5nfXMf5xia1YOoD5FEWtAwYDJPdi2nKQVo++K2YUSikh a/QJ+w2LDn3o+0JPk2a531jV5kVQLVekmuSpnC6lZ5yA2KmKhiiJgK3bA6JXHVpUlR5M89cy6VHmJ5 X26TB25wojZJtvAnpSCgRXs4mudT6hUZb/PqXrrPDDgSx+hLg3rBiuWQCF0HbrQEU+p6VOjnLzj/Zp 84lF3VZiWegKOPq14Br1mVD9ZMey/cqoozhcNRQN6UQVJjjjHtzknvRisrsDMx0ueJp5ephQroRMcV I9cwWr38G37qkYc1EHRiR3VU01Dtn+ X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Stat-Signature: 3u77qhrqmrrurwk5fiziijq8ag85q8ym X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: AA5E64001A X-Rspam-User: X-HE-Tag: 1690203033-137677 X-HE-Meta: U2FsdGVkX1+SeGAf+tphirnj9flNgCntswGlGu/OuEaQFlwvQsPBA3HED8MLI0pywWIuaOKzinvqJcg6qIuwT8tD0kx3Dgl048w/eloFOPQIrsZwGK6N1cvNPAtJQGq7j29qx5y1GVJp6uN/9a/XzNYfIXzH/xaUaQ7SphiUAmeOKTq5tNRbZWoWm0hITndkLFbxBhvG3F+wF8a9eucXfHzB1/mnWWn6aBHlQTt9qcB4ZrTyFQi4W662zJ1ZS2tnVk+RJgh0tAPG79lAJO+923vT/fEghFd1bdbphtVm1kLV+brWV7ZheacRUynD2v3fJJRVbNZkTF/wO3rA5Byn7UaeSxljq3PxnI+/4mfi8opegkJtAv6FmVMEBsSsa/zxNi4TvO9PFmYNGtXRSn/A1xQnxk+xpLQl82MnwuahnQlbBnhV1ERSTfnT6L6HnM+nC6+btgzZDewhRRr17vsNFsgZd0dO2YcxhQMp4W3gH7EdkgWQU0EovIDcSW5FgfwC1PDysst1QGIaluX6Za2S1dfcxNBBZlEbtidJAA2dSD/OK6AaE6Wy24tfjEBaH+5pawDXzMb1aY0xb2K7T8h1xvSIUbB+bv3tfvKq9Rh7pSkpxg+e5UwKXxB2e5BQKiqQcnOBzqO8G95qlZOlhbz+1bDFYM6qpVLq2JWrdJli1B0DhQiyvd3qin+REpGK5RSLS8bx7YJVJZl7YGwpukwZEIDQCAyI/Mit8MIWVGK+fhfvdE6ljyjksUh5dEB4PxjxhsZ3rWloqcXJWtWhAOC92OKBWEFxQIuRAHY9V5EU+qZns62aH81bsuT5sM+8ogGFma6JJVnTy86saQKg0dC51fSh+nljcdKR+utWVlpvs1sZs/S7iNGsQM+vOAITi4L37x8SGkAySyf1DPzpKDiCw3odRztRYfcF/BWkz/ljijig2dZd9LyiSU41Hg6pHHBWIjbtiY3QcPbGdLP7OJW QZwNZ4at oS8G5gGLhmt9IZkhaLadERLJHIUI2cbdLVEHMhKaiaN4QlKJnYu6QO2trODiPZyX3KxrnG2t4qBW+QUxB2RC2cbhic+3cyTjw941IpTI8qfa5bJBpAiJ2wE4nDdWxRMB4KieA2Z3y4tdbgz2kxUen7rsCitvei8P2KT4t6F8fT87h2iZbqD/SU3R/Q1D/TWkxuH0DdhdmJO1As+pfqAzamKjtt3s9mX1N1GoWuIcPPsqBQqCDjunFq/1zN6N22uDrBRCfcOLq37rpzloCESEsd7dnt1JQkmnlRBrNehcwna2E26o/rdExdTlXxKABCzx5yE5Hey3c+kxJT2ieGFXw15zn8aneklwIcZidKdFwmLO5rFiXAyiX1GaoAXe7Gr3D6bnt+pvANLOTmCeucwiM/gMCC2K/SMYwlHX+5a51OMdHg4E= 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: Verify that we can lock individual GCS mode bits, that other modes aren't affected and as a side effect also that every combination of modes can be enabled. Normally the inability to reenable GCS after disabling it would be an issue with testing but fortunately the kselftest_harness runs each test within a fork()ed child. This can be inconvenient for some kinds of testing but here it means that each test is in a separate thread and therefore won't be affected by other tests in the suite. Once we get toolchains with support for enabling GCS by default we will need to take care to not do that in the build system but there are no such toolchains yet so it is not yet an issue. Signed-off-by: Mark Brown --- tools/testing/selftests/arm64/gcs/.gitignore | 1 + tools/testing/selftests/arm64/gcs/Makefile | 2 +- tools/testing/selftests/arm64/gcs/gcs-locking.c | 200 ++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore index 5810c4a163d4..0c86f53f68ad 100644 --- a/tools/testing/selftests/arm64/gcs/.gitignore +++ b/tools/testing/selftests/arm64/gcs/.gitignore @@ -1,2 +1,3 @@ basic-gcs libc-gcs +gcs-locking diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile index 31fbd3a6bf27..340c6cca6cc9 100644 --- a/tools/testing/selftests/arm64/gcs/Makefile +++ b/tools/testing/selftests/arm64/gcs/Makefile @@ -6,7 +6,7 @@ # nolibc. # -TEST_GEN_PROGS := basic-gcs libc-gcs +TEST_GEN_PROGS := basic-gcs libc-gcs gcs-locking LDLIBS+=-lpthread diff --git a/tools/testing/selftests/arm64/gcs/gcs-locking.c b/tools/testing/selftests/arm64/gcs/gcs-locking.c new file mode 100644 index 000000000000..f6a73254317e --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/gcs-locking.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2023 ARM Limited. + * + * Tests for GCS mode locking. These tests rely on both having GCS + * unconfigured on entry and on the kselftest harness running each + * test in a fork()ed process which will have it's own mode. + */ + +#include + +#include +#include + +#include + +#include "kselftest_harness.h" + +#include "gcs-util.h" + +#define my_syscall2(num, arg1, arg2) \ +({ \ + register long _num __asm__ ("x8") = (num); \ + register long _arg1 __asm__ ("x0") = (long)(arg1); \ + register long _arg2 __asm__ ("x1") = (long)(arg2); \ + register long _arg3 __asm__ ("x2") = 0; \ + register long _arg4 __asm__ ("x3") = 0; \ + register long _arg5 __asm__ ("x4") = 0; \ + \ + __asm__ volatile ( \ + "svc #0\n" \ + : "=r"(_arg1) \ + : "r"(_arg1), "r"(_arg2), \ + "r"(_arg3), "r"(_arg4), \ + "r"(_arg5), "r"(_num) \ + : "memory", "cc" \ + ); \ + _arg1; \ +}) + +/* No mode bits are rejected for locking */ +TEST(lock_all_modes) +{ + int ret; + + ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, ULONG_MAX, 0, 0, 0); + ASSERT_EQ(ret, 0); +} + +FIXTURE(valid_modes) +{ +}; + +FIXTURE_VARIANT(valid_modes) +{ + unsigned long mode; +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable) +{ + .mode = PR_SHADOW_STACK_ENABLE, +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable_write) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE, +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable_push) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH, +}; + +FIXTURE_VARIANT_ADD(valid_modes, enable_write_push) +{ + .mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | + PR_SHADOW_STACK_PUSH, +}; + +FIXTURE_SETUP(valid_modes) +{ +} + +FIXTURE_TEARDOWN(valid_modes) +{ +} + +/* We can set the mode at all */ +TEST_F(valid_modes, set) +{ + int ret; + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + variant->mode); + ASSERT_EQ(ret, 0); + + _exit(0); +} + +/* Enabling, locking then disabling is rejected */ +TEST_F(valid_modes, enable_lock_disable) +{ + unsigned long mode; + int ret; + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + variant->mode); + ASSERT_EQ(ret, 0); + + ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + ASSERT_EQ(mode, variant->mode); + + ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, variant->mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, 0); + ASSERT_EQ(ret, -EBUSY); + + _exit(0); +} + +/* Locking then enabling is rejected */ +TEST_F(valid_modes, lock_enable) +{ + unsigned long mode; + int ret; + + ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, variant->mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + variant->mode); + ASSERT_EQ(ret, -EBUSY); + + ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + ASSERT_EQ(mode, 0); + + _exit(0); +} + +/* Locking then changing other modes is fine */ +TEST_F(valid_modes, lock_enable_disable_others) +{ + unsigned long mode; + int ret; + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + variant->mode); + ASSERT_EQ(ret, 0); + + ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + ASSERT_EQ(mode, variant->mode); + + ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, variant->mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + PR_SHADOW_STACK_ALL_MODES); + ASSERT_EQ(ret, 0); + + ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + ASSERT_EQ(mode, PR_SHADOW_STACK_ALL_MODES); + + + ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, + variant->mode); + ASSERT_EQ(ret, 0); + + ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); + ASSERT_EQ(ret, 0); + ASSERT_EQ(mode, variant->mode); + + _exit(0); +} + +int main(int argc, char **argv) +{ + unsigned long mode; + int ret; + + if (!(getauxval(AT_HWCAP2) & HWCAP2_GCS)) + ksft_exit_skip("SKIP GCS not supported\n"); + + ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); + if (ret) { + ksft_print_msg("Failed to read GCS state: %d\n", ret); + return EXIT_FAILURE; + } + + if (mode & PR_SHADOW_STACK_ENABLE) { + ksft_print_msg("GCS was enabled, test unsupported\n"); + return KSFT_SKIP; + } + + return test_harness_run(argc, argv); +} -- 2.30.2