Explorar el Código

Tests: Add a test to ensure sigaltstack() is working correctly

Idan Horowitz hace 3 años
padre
commit
246255527a
Se han modificado 2 ficheros con 60 adiciones y 0 borrados
  1. 1 0
      Tests/Kernel/CMakeLists.txt
  2. 59 0
      Tests/Kernel/TestSigAltStack.cpp

+ 1 - 0
Tests/Kernel/CMakeLists.txt

@@ -41,6 +41,7 @@ set(LIBTEST_BASED_SOURCES
     TestMunMap.cpp
     TestProcFS.cpp
     TestProcFSWrite.cpp
+    TestSigAltStack.cpp
 )
 
 foreach(libtest_source IN LISTS LIBTEST_BASED_SOURCES)

+ 59 - 0
Tests/Kernel/TestSigAltStack.cpp

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifdef __clang__
+#    pragma clang optimize off
+#else
+#    pragma GCC optimize("O0")
+#endif
+
+#include <LibTest/TestCase.h>
+#include <signal.h>
+#include <unistd.h>
+
+static void signal_handler(int)
+{
+    // We execute this syscall in order to force the kernel to perform the syscall precondition validation which
+    // checks that we have correctly set up the stack region to match our currently implemented protections.
+    getuid();
+    _exit(0);
+}
+
+#ifdef __clang__
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Winfinite-recursion"
+#endif
+static size_t infinite_recursion(size_t input)
+{
+    return infinite_recursion(input) + 1;
+}
+#ifdef __clang__
+#    pragma clang diagnostic pop
+#endif
+
+// This test can only pass with sigaltstack correctly enabled, as otherwise the SIGSEGV signal handler itself would also fault due to the overflown stack.
+TEST_CASE(success_case)
+{
+    static u8 alt_stack[SIGSTKSZ];
+    stack_t ss = {
+        .ss_sp = alt_stack,
+        .ss_flags = 0,
+        .ss_size = SIGSTKSZ,
+    };
+    auto res = sigaltstack(&ss, nullptr);
+    EXPECT_EQ(res, 0);
+
+    struct sigaction sa;
+    sa.sa_handler = signal_handler;
+    sa.sa_flags = SA_ONSTACK;
+    res = sigfillset(&sa.sa_mask);
+    EXPECT_EQ(res, 0);
+    res = sigaction(SIGSEGV, &sa, 0);
+    EXPECT_EQ(res, 0);
+
+    (void)infinite_recursion(0);
+    FAIL("Infinite recursion finished successfully");
+}