Serenity Operating System
at master 57 lines 1.5 kB view raw
1/* 2 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Platform.h> 8 9#if defined(AK_COMPILER_CLANG) 10# pragma clang optimize off 11#else 12# pragma GCC optimize("O0") 13#endif 14 15#include <LibTest/TestCase.h> 16#include <signal.h> 17#include <unistd.h> 18 19static void signal_handler(int) 20{ 21 // We execute this syscall in order to force the kernel to perform the syscall precondition validation which 22 // checks that we have correctly set up the stack region to match our currently implemented protections. 23 getuid(); 24 _exit(0); 25} 26 27#pragma GCC diagnostic push 28#pragma GCC diagnostic ignored "-Winfinite-recursion" 29static size_t infinite_recursion(size_t input) 30{ 31 return infinite_recursion(input) + 1; 32} 33#pragma GCC diagnostic pop 34 35// This test can only pass with sigaltstack correctly enabled, as otherwise the SIGSEGV signal handler itself would also fault due to the overflown stack. 36TEST_CASE(success_case) 37{ 38 static u8 alt_stack[SIGSTKSZ]; 39 stack_t ss = { 40 .ss_sp = alt_stack, 41 .ss_flags = 0, 42 .ss_size = SIGSTKSZ, 43 }; 44 auto res = sigaltstack(&ss, nullptr); 45 EXPECT_EQ(res, 0); 46 47 struct sigaction sa; 48 sa.sa_handler = signal_handler; 49 sa.sa_flags = SA_ONSTACK; 50 res = sigfillset(&sa.sa_mask); 51 EXPECT_EQ(res, 0); 52 res = sigaction(SIGSEGV, &sa, 0); 53 EXPECT_EQ(res, 0); 54 55 (void)infinite_recursion(0); 56 FAIL("Infinite recursion finished successfully"); 57}