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