From 246255527a9c4ea57ddb4b13d3f1c7f587148f53 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 30 Nov 2021 01:10:18 +0200 Subject: [PATCH] Tests: Add a test to ensure sigaltstack() is working correctly --- Tests/Kernel/CMakeLists.txt | 1 + Tests/Kernel/TestSigAltStack.cpp | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 Tests/Kernel/TestSigAltStack.cpp diff --git a/Tests/Kernel/CMakeLists.txt b/Tests/Kernel/CMakeLists.txt index 2b1364a667..ef37bc29dc 100644 --- a/Tests/Kernel/CMakeLists.txt +++ b/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) diff --git a/Tests/Kernel/TestSigAltStack.cpp b/Tests/Kernel/TestSigAltStack.cpp new file mode 100644 index 0000000000..0bcc64d191 --- /dev/null +++ b/Tests/Kernel/TestSigAltStack.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifdef __clang__ +# pragma clang optimize off +#else +# pragma GCC optimize("O0") +#endif + +#include +#include +#include + +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"); +}