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