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
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(waitstatus: &status);
37 ASSERT_TRUE(cpid > 0);
38 ASSERT_EQ(cpid, pid);
39 ASSERT_TRUE(WIFEXITED(status));
40}
41
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(waitstatus: &status);
59 ASSERT_TRUE(cpid > 0);
60 ASSERT_EQ(cpid, pid);
61 ASSERT_TRUE(WTERMSIG(status) == SIGABRT);
62}
63
64TEST_MAIN(int argc, char **argv, char **envp) {
65 no_stack_smashing_normal_exit();
66 stack_smashing_abort();
67 return 0;
68}
69

source code of libc/test/integration/src/unistd/stack_smashing_test.cpp