Received: by 2002:a05:6358:c692:b0:131:369:b2a3 with SMTP id fe18csp4472083rwb; Mon, 31 Jul 2023 07:24:41 -0700 (PDT) X-Google-Smtp-Source: APBJJlEzftp0p/X15n4zJSzMkkAN+Lt0gEZhSp+v1IVlMmpbEeUUJrsT8RezJgrnRbuCyUEfuC8J X-Received: by 2002:a05:6a00:2291:b0:687:3110:7fa8 with SMTP id f17-20020a056a00229100b0068731107fa8mr4422326pfe.14.1690813480825; Mon, 31 Jul 2023 07:24:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690813480; cv=none; d=google.com; s=arc-20160816; b=GMzg5VA4czYvtjBu5UJ9QngrPDvEGS/cyUszvfkGvb1qc7FJFurXKCHBtn/sEk4W6D CZ8/3gG67xlt7UcWiGULxc9sKEuAmdk1qisHRKepMi0m0AsyUkYqu4xuxe1YowcRtAaP Rd4+N/6oN5MBAgFrwHt9gyO2zXyzJ4O5+1dtaUPXhXRkZeIvWd1QHBRxbulEhSANN/aM CChl0S9PVPOVYXLOLiqMN92xP5H1enWXwpR7bjANWW+KmJPtzQcdjyl16QI/0U3scsq4 iltfYkD/gqSIzdiM3WL1QvUoZykx/jLYKaMhUuimwCicmEvUr5IfPsDfVAIvddBJUFA7 NzVA== 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=XJbY1bFU7w0cPaQF6eYkdTRefgro7AfSI1KvzwfLPNE=; fh=EdAFSmIgUzZTC6WCy4Jg1wBZ0/m6m2d/OjiRUJ3BsTI=; b=YRp3sXcnQyMW8wq9lI3/bq/qdR5ISQ9NTJ7NCc5wS+CPInbeIDyeisoGZEdVJ1QJqR DGJAsxe1r3PXDUmRljT2vBghIccInvahgUbCqK0/RIGwWwDjZmATDaF0u6No3RlDiHM7 6iKdd4FKp9MvPOdH0vbMANhFCylJJ/GPat6t0nfkw9SpLkFieR2FhkQGQIHEt+n6LcOf 9lnp8DxzMl7p8zcKSQjnc7yfLYlA20GbBth6jwY4TxomA33/uOGnrtFBGg304AlQUKqb 2M/QQRAIm3g7KpcKy7wjUJl7Od12HJ6K8EuBeqtre6v0WUfIvNiA9/sXBdiOGMp94xMM nDCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RMXweSck; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d3-20020a63f243000000b00550e8b1ebc1si7470809pgk.339.2023.07.31.07.24.26; Mon, 31 Jul 2023 07:24:40 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RMXweSck; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232828AbjGaN6p (ORCPT + 99 others); Mon, 31 Jul 2023 09:58:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233236AbjGaN6D (ORCPT ); Mon, 31 Jul 2023 09:58:03 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 168384C03; Mon, 31 Jul 2023 06:54:16 -0700 (PDT) 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 D13DF6115B; Mon, 31 Jul 2023 13:54:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF9AAC433C8; Mon, 31 Jul 2023 13:54:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690811656; bh=h9bKdgMYA3yorcV7MRrWgctU4KZ0wYlnm+mQUdEZpv0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RMXweSckzauEJRb840x4AR0huO5H7yfavmLxKVXMyd0CAFl7cpebVFEWGwuAXaky1 lJaIksXE4fig6jEP66n3SV/fg1xV3dTuYVk5H56hVYGiHgatUOHCaiZHkyiyE6q0Ss t1kkRXARrsD+tLy23IYMwBdqAdz5BeWeailItHkX783fxwjhWROjumQbUtu8o+3BK7 /CCF7w9PcE/CKDVSIkF2i8rvzhxzG8msvISWclRugUmc8j73wfuvFDhNHb7rMuWklM fKd2AL/JE7wngUbzXuTt4vqri66yQK7n280kXCUA53H71dEV/0TvepbgPDHUdc776x ylgsQzqHK1CrA== From: Mark Brown Date: Mon, 31 Jul 2023 14:43:42 +0100 Subject: [PATCH v3 33/36] 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: <20230731-arm64-gcs-v3-33-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=7316; i=broonie@kernel.org; h=from:subject:message-id; bh=h9bKdgMYA3yorcV7MRrWgctU4KZ0wYlnm+mQUdEZpv0=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBkx7wu00InVhHIHLEqB+nwnxI5YpOf/1mGfldLVoai 0tbFyUqJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZMe8LgAKCRAk1otyXVSH0OElB/ 9LnvPQwszI1MaevBl4Tn7mQ072S0+MxAgoweAbOg5GV6xMyIMVxPyAc4DBgVRO9zaMOxjjs71zeXtG X6U9f52BKVDC0eUjSZPDmUzTZXkldN+FSsJ73HIJgn9Zm+3uKg1405ELAchNX7h5EXuuhiaHn64vh5 B0P3JGaNUEM3aJoj7GXZnBzgKu/1c3tz/KsmZWAQDahhlk/IgtAyMexjfoJql+rdLUE2TejZlwtHLH 1zgVP0O9964VGMx0OM/d3nFpGYp9w10RIwjSIBK8hOGtwiYG36rWaeK7RU0IvnSd3ZLHn/cXLJU823 J2zx0JCRxTUoc7b+fo73olJGThBaDG X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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