xref: /aosp_15_r20/external/llvm-libc/test/integration/src/unistd/stack_smashing_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===--- Stack smashing test to check stack canary set up  ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/CPP/string.h"
10 #include "src/__support/OSUtil/io.h"
11 #include "src/pthread/pthread_atfork.h"
12 #include "src/signal/raise.h"
13 #include "src/sys/wait/wait.h"
14 #include "src/sys/wait/wait4.h"
15 #include "src/sys/wait/waitpid.h"
16 #include "src/unistd/fork.h"
17 
18 #include "test/IntegrationTest/test.h"
19 
20 #include <signal.h>
21 #include <sys/wait.h>
22 #include <unistd.h>
23 
no_stack_smashing_normal_exit()24 void no_stack_smashing_normal_exit() {
25   pid_t pid = LIBC_NAMESPACE::fork();
26   if (pid == 0) {
27     // Child process
28     char foo[30];
29     for (int i = 0; i < 30; i++)
30       foo[i] = (foo[i] != 42) ? 42 : 24;
31     return;
32   }
33   ASSERT_TRUE(pid > 0);
34   int status;
35   pid_t cpid = LIBC_NAMESPACE::wait(&status);
36   ASSERT_TRUE(cpid > 0);
37   ASSERT_EQ(cpid, pid);
38   ASSERT_TRUE(WIFEXITED(status));
39 }
40 
stack_smashing_abort()41 void stack_smashing_abort() {
42   pid_t pid = LIBC_NAMESPACE::fork();
43   if (pid == 0) {
44     // Child process
45     char foo[30];
46     char *frame_ptr = static_cast<char *>(__builtin_frame_address(0));
47     char *cur_ptr = &foo[0];
48     // Corrupt the stack
49     while (cur_ptr != frame_ptr) {
50       *cur_ptr = (*cur_ptr != 42) ? 42 : 24;
51       cur_ptr++;
52     }
53     return;
54   }
55   ASSERT_TRUE(pid > 0);
56   int status;
57   pid_t cpid = LIBC_NAMESPACE::wait(&status);
58   ASSERT_TRUE(cpid > 0);
59   ASSERT_EQ(cpid, pid);
60   ASSERT_TRUE(WTERMSIG(status) == SIGABRT);
61 }
62 
TEST_MAIN(int argc,char ** argv,char ** envp)63 TEST_MAIN(int argc, char **argv, char **envp) {
64   no_stack_smashing_normal_exit();
65   stack_smashing_abort();
66   return 0;
67 }
68