• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <err.h>
6 #include <fcntl.h>
7 #include <signal.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <unistd.h>
11 
12 #include "clang-fortify-common.h"
13 
14 // It's potentially easy for us to get blocked if a FORTIFY'ed I/O call isn't
15 // properly verified.
SetTimeout(int secs)16 static void SetTimeout(int secs) {
17   struct sigaction sigact;
18   bzero(&sigact, sizeof(sigact));
19 
20   sigact.sa_flags = SA_RESETHAND;
21   sigact.sa_handler = [](int) {
22     const char complaint[] = "!!! Timeout reached; abort abort abort\n";
23     (void)write(STDOUT_FILENO, complaint, strlen(complaint));
24     _exit(1);
25   };
26 
27   if (sigaction(SIGALRM, &sigact, nullptr))
28     err(1, "Failed to establish a SIGALRM handler");
29 
30   alarm(secs);
31 }
32 
PrintFailures(const std::vector<Failure> & failures)33 static void PrintFailures(const std::vector<Failure> &failures) {
34   fprintf(stderr, "Failure(s): (%zu total)\n", failures.size());
35   for (const Failure &f : failures) {
36     const char *why = f.expected_death ? "didn't die" : "died";
37     fprintf(stderr, "\t`%s` at line %d %s\n", f.message, f.line, why);
38   }
39 }
40 
main()41 int main() {
42   // On my dev machine, this test takes around 70ms to run to completion. On
43   // samus, it's more like 20 seconds.
44   SetTimeout(300);
45 
46   // Some functions (e.g. gets()) try to read from stdin. Stop them from doing
47   // so, lest they block forever.
48   int dev_null = open("/dev/null", O_RDONLY);
49   if (dev_null < 0)
50     err(1, "Failed opening /dev/null");
51 
52   if (dup2(dev_null, STDIN_FILENO) < 0)
53     err(1, "Failed making stdin == /dev/null");
54 
55   bool failed = false;
56 
57   fprintf(stderr, "::: Testing _FORTIFY_SOURCE=1 :::\n");
58   std::vector<Failure> failures = test_fortify_1();
59   if (!failures.empty()) {
60     PrintFailures(failures);
61     failed = true;
62   }
63 
64   fprintf(stderr, "::: Testing _FORTIFY_SOURCE=2 :::\n");
65   failures = test_fortify_2();
66   if (!failures.empty()) {
67     PrintFailures(failures);
68     failed = true;
69   }
70 
71   return failed ? 1 : 0;
72 }
73