mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
To: "dietmar.eggemann@arm.com" <dietmar.eggemann@arm.com>,
	"broonie@kernel.org" <broonie@kernel.org>,
	"Szabolcs.Nagy@arm.com" <Szabolcs.Nagy@arm.com>,
	"brauner@kernel.org" <brauner@kernel.org>,
	"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
	"debug@rivosinc.com" <debug@rivosinc.com>,
	"mgorman@suse.de" <mgorman@suse.de>,
	"vincent.guittot@linaro.org" <vincent.guittot@linaro.org>,
	"fweimer@redhat.com" <fweimer@redhat.com>,
	"mingo@redhat.com" <mingo@redhat.com>,
	"rostedt@goodmis.org" <rostedt@goodmis.org>,
	"hjl.tools@gmail.com" <hjl.tools@gmail.com>,
	"tglx@linutronix.de" <tglx@linutronix.de>,
	"vschneid@redhat.com" <vschneid@redhat.com>,
	"shuah@kernel.org" <shuah@kernel.org>,
	"bristot@redhat.com" <bristot@redhat.com>,
	"hpa@zytor.com" <hpa@zytor.com>,
	"peterz@infradead.org" <peterz@infradead.org>,
	"bp@alien8.de" <bp@alien8.de>,
	"bsegall@google.com" <bsegall@google.com>,
	"x86@kernel.org" <x86@kernel.org>,
	"juri.lelli@redhat.com" <juri.lelli@redhat.com>
Cc: "keescook@chromium.org" <keescook@chromium.org>,
	"jannh@google.com" <jannh@google.com>,
	"linux-kselftest@vger.kernel.org"
	<linux-kselftest@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"catalin.marinas@arm.com" <catalin.marinas@arm.com>,
	"linux-api@vger.kernel.org" <linux-api@vger.kernel.org>,
	"will@kernel.org" <will@kernel.org>
Subject: Re: [PATCH RFT v4 5/5] kselftest/clone3: Test shadow stack support
Date: Tue, 5 Dec 2023 00:10:20 +0000	[thread overview]
Message-ID: <4898975452179af46f38daa6979b32ba94001419.camel@intel.com> (raw)
In-Reply-To: <20231128-clone3-shadow-stack-v4-5-8b28ffe4f676@kernel.org>

On Tue, 2023-11-28 at 18:22 +0000, Mark Brown wrote:
> +
> +#define ENABLE_SHADOW_STACK
> +static inline void enable_shadow_stack(void)
> +{
> +       int ret = ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK);
> +       if (ret == 0)
> +               shadow_stack_enabled = true;
> +}
> +
> +#endif
> +
> +#ifndef ENABLE_SHADOW_STACK
> +static void enable_shadow_stack(void)
> +{
> +}
> +#endif

Without this diff, the test crashed for me on a shadow stack system:
diff --git a/tools/testing/selftests/clone3/clone3.c
b/tools/testing/selftests/clone3/clone3.c
index dbe52582573c..3236d97ed261 100644
--- a/tools/testing/selftests/clone3/clone3.c
+++ b/tools/testing/selftests/clone3/clone3.c
@@ -423,7 +423,7 @@ static const struct test tests[] = {
 })
 
 #define ENABLE_SHADOW_STACK
-static inline void enable_shadow_stack(void)
+static inline __attribute__((always_inline)) void
enable_shadow_stack(void)
 {
        int ret = ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK);
        if (ret == 0)

The fix works by making sure control flow never returns to before the
point shadow stack was enabled. Otherwise it will underflow the shadow
stack.



But I wonder if the clone3 test should get its shadow stack enabled the
conventional elf bit way. So if it's all there (HW, kernel, glibc) then
the test will run with shadow stack. Otherwise the test will run
without shadow stack.

The other reason is that the shadow stack test in the x86 selftest
manual enabling is designed to work without a shadow stack enabled
glibc and has to be specially crafted to work around the missing
support. I'm not sure the more generic selftests should have to know
how to do this. So what about something like this instead:

diff --git a/tools/testing/selftests/clone3/Makefile
b/tools/testing/selftests/clone3/Makefile
index 84832c369a2e..792bc9685c82 100644
--- a/tools/testing/selftests/clone3/Makefile
+++ b/tools/testing/selftests/clone3/Makefile
@@ -2,6 +2,13 @@
 CFLAGS += -g -std=gnu99 $(KHDR_INCLUDES)
 LDLIBS += -lcap
 
+ifeq ($(shell uname -m),x86_64)
+CAN_BUILD_WITH_SHSTK := $(shell ../x86/check_cc.sh gcc
../x86/trivial_program.c -mshstk -fcf-protection)
+ifeq ($(CAN_BUILD_WITH_SHSTK),1)
+CFLAGS += -mshstk -fcf-protection=return
+endif
+endif
+
 TEST_GEN_PROGS := clone3 clone3_clear_sighand clone3_set_tid \
        clone3_cap_checkpoint_restore
 
diff --git a/tools/testing/selftests/clone3/clone3.c
b/tools/testing/selftests/clone3/clone3.c
index dbe52582573c..eff5e8d5a5a6 100644
--- a/tools/testing/selftests/clone3/clone3.c
+++ b/tools/testing/selftests/clone3/clone3.c
@@ -23,7 +23,6 @@
 #include "clone3_selftests.h"
 
 static bool shadow_stack_enabled;
-static bool shadow_stack_supported;
 static size_t max_supported_args_size;
 
 enum test_mode {
@@ -50,36 +49,6 @@ struct test {
        filter_function filter;
 };
 
-#ifndef __NR_map_shadow_stack
-#define __NR_map_shadow_stack 453
-#endif
-
-/*
- * We check for shadow stack support by attempting to use
- * map_shadow_stack() since features may have been locked by the
- * dynamic linker resulting in spurious errors when we attempt to
- * enable on startup.  We warn if the enable failed.
- */
-static void test_shadow_stack_supported(void)
-{
-        long shadow_stack;
-
-       shadow_stack = syscall(__NR_map_shadow_stack, 0, getpagesize(),
0);
-       if (shadow_stack == -1) {
-               ksft_print_msg("map_shadow_stack() not supported\n");
-       } else if ((void *)shadow_stack == MAP_FAILED) {
-               ksft_print_msg("Failed to map shadow stack\n");
-       } else {
-               ksft_print_msg("Shadow stack supportd\n");
-               shadow_stack_supported = true;
-
-               if (!shadow_stack_enabled)
-                       ksft_print_msg("Mapped but did not enable
shadow stack\n");
-
-               munmap((void *)shadow_stack, getpagesize());
-       }
-}
-
 static int call_clone3(uint64_t flags, size_t size, enum test_mode
test_mode)
 {
        struct __clone_args args = {
@@ -220,7 +189,7 @@ static bool no_timenamespace(void)
 
 static bool have_shadow_stack(void)
 {
-       if (shadow_stack_supported) {
+       if (shadow_stack_enabled) {
                ksft_print_msg("Shadow stack supported\n");
                return true;
        }
@@ -230,7 +199,7 @@ static bool have_shadow_stack(void)
 
 static bool no_shadow_stack(void)
 {
-       if (!shadow_stack_supported) {
+       if (!shadow_stack_enabled) {
                ksft_print_msg("Shadow stack not supported\n");
                return true;
        }
@@ -402,38 +371,18 @@ static const struct test tests[] = {
 };
 
 #ifdef __x86_64__
-#define ARCH_SHSTK_ENABLE      0x5001
+#define ARCH_SHSTK_STATUS      0x5005
 #define ARCH_SHSTK_SHSTK       (1ULL <<  0)
 
-#define ARCH_PRCTL(arg1, arg2)                                 \
-({                                                             \
-       long _ret;                                              \
-       register long _num  asm("eax") = __NR_arch_prctl;       \
-       register long _arg1 asm("rdi") = (long)(arg1);          \
-       register long _arg2 asm("rsi") = (long)(arg2);          \
-                                                               \
-       asm volatile (                                          \
-               "syscall\n"                                     \
-               : "=a"(_ret)                                    \
-               : "r"(_arg1), "r"(_arg2),                       \
-                 "0"(_num)                                     \
-               : "rcx", "r11", "memory", "cc"                  \
-       );                                                      \
-       _ret;                                                   \
-})
-
-#define ENABLE_SHADOW_STACK
-static inline void enable_shadow_stack(void)
+static inline __attribute__((always_inline)) void
check_shadow_stack(void)
 {
-       int ret = ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK);
-       if (ret == 0)
-               shadow_stack_enabled = true;
+       unsigned long status = 0;
+
+       syscall(SYS_arch_prctl, ARCH_SHSTK_STATUS, &status);
+       shadow_stack_enabled = status & ARCH_SHSTK_SHSTK;
 }
-
-#endif
-
-#ifndef ENABLE_SHADOW_STACK
-static void enable_shadow_stack(void)
+#else /* __x86_64__ */
+static void check_shadow_stack(void)
 {
 }
 #endif
@@ -443,12 +392,11 @@ int main(int argc, char *argv[])
        size_t size;
        int i;
 
-       enable_shadow_stack();
+       check_shadow_stack();
 
        ksft_print_header();
        ksft_set_plan(ARRAY_SIZE(tests));
        test_clone3_supported();
-       test_shadow_stack_supported();
 
        for (i = 0; i < ARRAY_SIZE(tests); i++)
                test_clone3(&tests[i]);




  reply	other threads:[~2023-12-05  0:10 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-28 18:22 [PATCH RFT v4 0/5] fork: Support shadow stacks in clone3() Mark Brown
2023-11-28 18:22 ` [PATCH RFT v4 1/5] mm: Introduce ARCH_HAS_USER_SHADOW_STACK Mark Brown
2023-11-28 18:22 ` [PATCH RFT v4 2/5] fork: Add shadow stack support to clone3() Mark Brown
2023-11-28 21:23   ` Deepak Gupta
2023-11-29 13:05     ` Mark Brown
2023-12-05  0:26   ` Edgecombe, Rick P
2023-12-05 15:51     ` Mark Brown
2023-12-05 22:23       ` Edgecombe, Rick P
2023-12-06 18:24         ` Mark Brown
2023-11-28 18:22 ` [PATCH RFT v4 3/5] selftests/clone3: Factor more of main loop into test_clone3() Mark Brown
2023-11-28 18:22 ` [PATCH RFT v4 4/5] selftests/clone3: Allow tests to flag if -E2BIG is a valid error code Mark Brown
2023-11-28 18:22 ` [PATCH RFT v4 5/5] kselftest/clone3: Test shadow stack support Mark Brown
2023-12-05  0:10   ` Edgecombe, Rick P [this message]
2023-12-05 15:05     ` Mark Brown
2023-12-05 16:01       ` Edgecombe, Rick P
2023-12-05 16:43         ` Mark Brown
2023-12-05 22:31           ` Edgecombe, Rick P
2023-12-06 18:42             ` Mark Brown
2023-11-30 19:00 ` [PATCH RFT v4 0/5] fork: Support shadow stacks in clone3() Catalin Marinas
2023-11-30 21:51   ` Mark Brown
2023-11-30 23:37     ` Edgecombe, Rick P
2023-12-01 14:00       ` Mark Brown
2023-12-01 11:50     ` Szabolcs Nagy
2023-12-01 13:47       ` Mark Brown
2023-12-01 17:30     ` Catalin Marinas
2023-12-01 18:28       ` Mark Brown
2023-12-09  0:59 ` Robert O'Callahan
2023-12-09  1:06   ` 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=4898975452179af46f38daa6979b32ba94001419.camel@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=Szabolcs.Nagy@arm.com \
    --cc=bp@alien8.de \
    --cc=brauner@kernel.org \
    --cc=bristot@redhat.com \
    --cc=broonie@kernel.org \
    --cc=bsegall@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=debug@rivosinc.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=fweimer@redhat.com \
    --cc=hjl.tools@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jannh@google.com \
    --cc=juri.lelli@redhat.com \
    --cc=keescook@chromium.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=shuah@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=will@kernel.org \
    --cc=x86@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

all inboxes | Powered by JetHome®