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()25void 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()42void 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)64TEST_MAIN(int argc, char **argv, char **envp) { 65 no_stack_smashing_normal_exit(); 66 stack_smashing_abort(); 67 return 0; 68 } 69