tools/nolibc: tests: add test for -fstack-protector
authorThomas Weißschuh <linux@weissschuh.net>
Sat, 25 Mar 2023 15:45:14 +0000 (16:45 +0100)
committerPaul E. McKenney <paulmck@kernel.org>
Mon, 27 Mar 2023 23:26:10 +0000 (16:26 -0700)
Test the previously introduce stack protector functionality in nolibc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
tools/testing/selftests/nolibc/Makefile
tools/testing/selftests/nolibc/nolibc-test.c

index 4469dcb0c9d77ea3e6b34a8e7cbd7c24a6d9face..e516e53775d4452b9513d557784d24b4d763d625 100644 (file)
@@ -76,6 +76,9 @@ else
 Q=@
 endif
 
+CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
+                       $(call cc-option,-mstack-protector-guard=global) \
+                       $(call cc-option,-fstack-protector-all)
 CFLAGS_s390 = -m64
 CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables \
                $(call cc-option,-fno-stack-protector) \
index fb2d4872fac9e198b4d6f720fe27228094627310..21bacc928bf7b260518496fcecd0cf2960628a27 100644 (file)
@@ -667,6 +667,63 @@ int run_stdlib(int min, int max)
        return ret;
 }
 
+#if defined(__clang__)
+__attribute__((optnone))
+#elif defined(__GNUC__)
+__attribute__((optimize("O0")))
+#endif
+static int smash_stack(void)
+{
+       char buf[100];
+
+       for (size_t i = 0; i < 200; i++)
+               buf[i] = 'P';
+
+       return 1;
+}
+
+static int run_protection(int min, int max)
+{
+       pid_t pid;
+       int llen = 0, status;
+
+       llen += printf("0 -fstackprotector ");
+
+#if !defined(NOLIBC_STACKPROTECTOR)
+       llen += printf("not supported");
+       pad_spc(llen, 64, "[SKIPPED]\n");
+       return 0;
+#endif
+
+       pid = -1;
+       pid = fork();
+
+       switch (pid) {
+       case -1:
+               llen += printf("fork()");
+               pad_spc(llen, 64, "[FAIL]\n");
+               return 1;
+
+       case 0:
+               close(STDOUT_FILENO);
+               close(STDERR_FILENO);
+
+               smash_stack();
+               return 1;
+
+       default:
+               pid = waitpid(pid, &status, 0);
+
+               if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {
+                       llen += printf("waitpid()");
+                       pad_spc(llen, 64, "[FAIL]\n");
+                       return 1;
+               }
+               pad_spc(llen, 64, " [OK]\n");
+               return 0;
+       }
+}
+
 /* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */
 int prepare(void)
 {
@@ -719,8 +776,9 @@ int prepare(void)
 /* This is the definition of known test names, with their functions */
 static const struct test test_names[] = {
        /* add new tests here */
-       { .name = "syscall",   .func = run_syscall  },
-       { .name = "stdlib",    .func = run_stdlib   },
+       { .name = "syscall",    .func = run_syscall    },
+       { .name = "stdlib",     .func = run_stdlib     },
+       { .name = "protection", .func = run_protection },
        { 0 }
 };