TestSigAltStack.cpp 1.5 KB

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