Adding uretprobe shadow stack test that runs all existing
uretprobe tests with shadow stack enabled if it's available.

Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 .../selftests/bpf/prog_tests/uprobe_syscall.c | 60 +++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c 
b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
index 3ef324c2db50..fda456401284 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
@@ -9,6 +9,9 @@
 #include <linux/compiler.h>
 #include <linux/stringify.h>
 #include <sys/wait.h>
+#include <sys/syscall.h>
+#include <sys/prctl.h>
+#include <asm/prctl.h>
 #include "uprobe_syscall.skel.h"
 #include "uprobe_syscall_executed.skel.h"
 
@@ -297,6 +300,56 @@ static void test_uretprobe_syscall_call(void)
        close(go[1]);
        close(go[0]);
 }
+
+/*
+ * Borrowed from tools/testing/selftests/x86/test_shadow_stack.c.
+ *
+ * For use in inline enablement of shadow stack.
+ *
+ * The program can't return from the point where shadow stack gets enabled
+ * because there will be no address on the shadow stack. So it can't use
+ * syscall() for enablement, since it is a function.
+ *
+ * Based on code from nolibc.h. Keep a copy here because this can't pull
+ * in all of nolibc.h.
+ */
+#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;                                                   \
+})
+
+#ifndef ARCH_SHSTK_ENABLE
+#define ARCH_SHSTK_ENABLE      0x5001
+#define ARCH_SHSTK_DISABLE     0x5002
+#define ARCH_SHSTK_SHSTK       (1ULL <<  0)
+#endif
+
+static void test_uretprobe_shadow_stack(void)
+{
+       if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK)) {
+               test__skip();
+               return;
+       }
+
+       /* Run all of the uretprobe tests. */
+       test_uretprobe_regs_equal();
+       test_uretprobe_regs_change();
+       test_uretprobe_syscall_call();
+
+       ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK);
+}
 #else
 static void test_uretprobe_regs_equal(void)
 {
@@ -312,6 +365,11 @@ static void test_uretprobe_syscall_call(void)
 {
        test__skip();
 }
+
+static void test_uretprobe_shadow_stack(void)
+{
+       test__skip();
+}
 #endif
 
 void test_uprobe_syscall(void)
@@ -322,4 +380,6 @@ void test_uprobe_syscall(void)
                test_uretprobe_regs_change();
        if (test__start_subtest("uretprobe_syscall_call"))
                test_uretprobe_syscall_call();
+       if (test__start_subtest("uretprobe_shadow_stack"))
+               test_uretprobe_shadow_stack();
 }
-- 
2.45.1


Reply via email to