• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <errno.h>
21 #include <signal.h>
22 #include <sys/wait.h>
23 #include <unistd.h>
24 
no_stack_smashing_normal_exit()25 void no_stack_smashing_normal_exit() {
26   pid_t pid = LIBC_NAMESPACE::fork();
27   if (pid == 0) {
28     // Child process
29     char foo[30];
30     for (int i = 0; i < 30; i++)
31       foo[i] = (foo[i] != 42) ? 42 : 24;
32     return;
33   }
34   ASSERT_TRUE(pid > 0);
35   int status;
36   pid_t cpid = LIBC_NAMESPACE::wait(&status);
37   ASSERT_TRUE(cpid > 0);
38   ASSERT_EQ(cpid, pid);
39   ASSERT_TRUE(WIFEXITED(status));
40 }
41 
stack_smashing_abort()42 void stack_smashing_abort() {
43   pid_t pid = LIBC_NAMESPACE::fork();
44   if (pid == 0) {
45     // Child process
46     char foo[30];
47     char *frame_ptr = static_cast<char *>(__builtin_frame_address(0));
48     char *cur_ptr = &foo[0];
49     // Corrupt the stack
50     while (cur_ptr != frame_ptr) {
51       *cur_ptr = (*cur_ptr != 42) ? 42 : 24;
52       cur_ptr++;
53     }
54     return;
55   }
56   ASSERT_TRUE(pid > 0);
57   int status;
58   pid_t cpid = LIBC_NAMESPACE::wait(&status);
59   ASSERT_TRUE(cpid > 0);
60   ASSERT_EQ(cpid, pid);
61   ASSERT_TRUE(WTERMSIG(status) == SIGABRT);
62 }
63 
TEST_MAIN(int argc,char ** argv,char ** envp)64 TEST_MAIN(int argc, char **argv, char **envp) {
65   no_stack_smashing_normal_exit();
66   stack_smashing_abort();
67   return 0;
68 }
69