Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/tools/fuzzing/libfuzzer/FuzzerUtilPosix.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- FuzzerUtilPosix.cpp - Misc utils for Posix. ------------------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
// Misc utils implementation using Posix API.
10
//===----------------------------------------------------------------------===//
11
#include "FuzzerDefs.h"
12
#if LIBFUZZER_POSIX
13
#include "FuzzerIO.h"
14
#include "FuzzerInternal.h"
15
#include <cassert>
16
#include <chrono>
17
#include <cstring>
18
#include <errno.h>
19
#include <iomanip>
20
#include <signal.h>
21
#include <stdio.h>
22
#include <sys/resource.h>
23
#include <sys/syscall.h>
24
#include <sys/time.h>
25
#include <sys/types.h>
26
#include <thread>
27
#include <unistd.h>
28
29
namespace fuzzer {
30
31
14
static void AlarmHandler(int, siginfo_t *, void *) {
32
14
  Fuzzer::StaticAlarmCallback();
33
14
}
34
35
0
static void CrashHandler(int, siginfo_t *, void *) {
36
0
  Fuzzer::StaticCrashSignalCallback();
37
0
}
38
39
0
static void InterruptHandler(int, siginfo_t *, void *) {
40
0
  Fuzzer::StaticInterruptCallback();
41
0
}
42
43
0
static void GracefulExitHandler(int, siginfo_t *, void *) {
44
0
  Fuzzer::StaticGracefulExitCallback();
45
0
}
46
47
0
static void FileSizeExceedHandler(int, siginfo_t *, void *) {
48
0
  Fuzzer::StaticFileSizeExceedCallback();
49
0
}
50
51
static void SetSigaction(int signum,
52
33
                         void (*callback)(int, siginfo_t *, void *)) {
53
33
  struct sigaction sigact = {};
54
33
  if (sigaction(signum, nullptr, &sigact)) {
55
0
    Printf("libFuzzer: sigaction failed with %d\n", errno);
56
0
    exit(1);
57
0
  }
58
33
  if (sigact.sa_flags & SA_SIGINFO) {
59
12
    if (sigact.sa_sigaction)
60
12
      return;
61
21
  } else {
62
21
    if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN &&
63
21
        sigact.sa_handler != SIG_ERR)
64
21
      return;
65
21
  }
66
21
67
21
  sigact = {};
68
21
  sigact.sa_sigaction = callback;
69
21
  if (sigaction(signum, &sigact, 0)) {
70
0
    Printf("libFuzzer: sigaction failed with %d\n", errno);
71
0
    exit(1);
72
0
  }
73
21
}
74
75
3
void SetTimer(int Seconds) {
76
3
  struct itimerval T {
77
3
    {Seconds, 0}, { Seconds, 0 }
78
3
  };
79
3
  if (setitimer(ITIMER_REAL, &T, nullptr)) {
80
0
    Printf("libFuzzer: setitimer failed with %d\n", errno);
81
0
    exit(1);
82
0
  }
83
3
  SetSigaction(SIGALRM, AlarmHandler);
84
3
}
85
86
3
void SetSignalHandler(const FuzzingOptions& Options) {
87
3
  if (Options.UnitTimeoutSec > 0)
88
3
    SetTimer(Options.UnitTimeoutSec / 2 + 1);
89
3
  if (Options.HandleInt)
90
3
    SetSigaction(SIGINT, InterruptHandler);
91
3
  if (Options.HandleTerm)
92
3
    SetSigaction(SIGTERM, InterruptHandler);
93
3
  if (Options.HandleSegv)
94
3
    SetSigaction(SIGSEGV, CrashHandler);
95
3
  if (Options.HandleBus)
96
3
    SetSigaction(SIGBUS, CrashHandler);
97
3
  if (Options.HandleAbrt)
98
3
    SetSigaction(SIGABRT, CrashHandler);
99
3
  if (Options.HandleIll)
100
3
    SetSigaction(SIGILL, CrashHandler);
101
3
  if (Options.HandleFpe)
102
3
    SetSigaction(SIGFPE, CrashHandler);
103
3
  if (Options.HandleXfsz)
104
3
    SetSigaction(SIGXFSZ, FileSizeExceedHandler);
105
3
  if (Options.HandleUsr1)
106
3
    SetSigaction(SIGUSR1, GracefulExitHandler);
107
3
  if (Options.HandleUsr2)
108
3
    SetSigaction(SIGUSR2, GracefulExitHandler);
109
3
}
110
111
801
void SleepSeconds(int Seconds) {
112
801
  sleep(Seconds); // Use C API to avoid coverage from instrumented libc++.
113
801
}
114
115
3
unsigned long GetPid() { return (unsigned long)getpid(); }
116
117
815
size_t GetPeakRSSMb() {
118
815
  struct rusage usage;
119
815
  if (getrusage(RUSAGE_SELF, &usage))
120
0
    return 0;
121
815
  if (LIBFUZZER_LINUX || LIBFUZZER_FREEBSD || LIBFUZZER_NETBSD ||
122
815
      LIBFUZZER_OPENBSD) {
123
815
    // ru_maxrss is in KiB
124
815
    return usage.ru_maxrss >> 10;
125
815
  } else if (LIBFUZZER_APPLE) {
126
0
    // ru_maxrss is in bytes
127
0
    return usage.ru_maxrss >> 20;
128
0
  }
129
0
  assert(0 && "GetPeakRSSMb() is not implemented for your platform");
130
0
  return 0;
131
0
}
132
133
0
FILE *OpenProcessPipe(const char *Command, const char *Mode) {
134
0
  return popen(Command, Mode);
135
0
}
136
137
const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
138
0
                         size_t PattLen) {
139
0
  return memmem(Data, DataLen, Patt, PattLen);
140
0
}
141
142
0
std::string DisassembleCmd(const std::string &FileName) {
143
0
  return "objdump -d " + FileName;
144
0
}
145
146
0
std::string SearchRegexCmd(const std::string &Regex) {
147
0
  return "grep '" + Regex + "'";
148
0
}
149
150
}  // namespace fuzzer
151
152
#endif // LIBFUZZER_POSIX