blob: bc64d3293702f12b2c8445627d43ca5d925ea2a3 [file] [log] [blame]
george.karpenkov29efa6d2017-08-21 23:25:50 +00001//===- 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>
george.karpenkov29efa6d2017-08-21 23:25:50 +000021#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
29namespace fuzzer {
30
31static void AlarmHandler(int, siginfo_t *, void *) {
32 Fuzzer::StaticAlarmCallback();
33}
34
35static void CrashHandler(int, siginfo_t *, void *) {
36 Fuzzer::StaticCrashSignalCallback();
37}
38
39static void InterruptHandler(int, siginfo_t *, void *) {
40 Fuzzer::StaticInterruptCallback();
41}
42
kcc1239a992017-11-09 20:30:19 +000043static void GracefulExitHandler(int, siginfo_t *, void *) {
44 Fuzzer::StaticGracefulExitCallback();
45}
46
george.karpenkov29efa6d2017-08-21 23:25:50 +000047static void FileSizeExceedHandler(int, siginfo_t *, void *) {
48 Fuzzer::StaticFileSizeExceedCallback();
49}
50
51static void SetSigaction(int signum,
52 void (*callback)(int, siginfo_t *, void *)) {
53 struct sigaction sigact = {};
54 if (sigaction(signum, nullptr, &sigact)) {
55 Printf("libFuzzer: sigaction failed with %d\n", errno);
56 exit(1);
57 }
58 if (sigact.sa_flags & SA_SIGINFO) {
59 if (sigact.sa_sigaction)
60 return;
61 } else {
62 if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN &&
63 sigact.sa_handler != SIG_ERR)
64 return;
65 }
66
67 sigact = {};
68 sigact.sa_sigaction = callback;
69 if (sigaction(signum, &sigact, 0)) {
70 Printf("libFuzzer: sigaction failed with %d\n", errno);
71 exit(1);
72 }
73}
74
75void SetTimer(int Seconds) {
76 struct itimerval T {
77 {Seconds, 0}, { Seconds, 0 }
78 };
79 if (setitimer(ITIMER_REAL, &T, nullptr)) {
80 Printf("libFuzzer: setitimer failed with %d\n", errno);
81 exit(1);
82 }
83 SetSigaction(SIGALRM, AlarmHandler);
84}
85
86void SetSignalHandler(const FuzzingOptions& Options) {
87 if (Options.UnitTimeoutSec > 0)
88 SetTimer(Options.UnitTimeoutSec / 2 + 1);
89 if (Options.HandleInt)
90 SetSigaction(SIGINT, InterruptHandler);
91 if (Options.HandleTerm)
92 SetSigaction(SIGTERM, InterruptHandler);
93 if (Options.HandleSegv)
94 SetSigaction(SIGSEGV, CrashHandler);
95 if (Options.HandleBus)
96 SetSigaction(SIGBUS, CrashHandler);
97 if (Options.HandleAbrt)
98 SetSigaction(SIGABRT, CrashHandler);
99 if (Options.HandleIll)
100 SetSigaction(SIGILL, CrashHandler);
101 if (Options.HandleFpe)
102 SetSigaction(SIGFPE, CrashHandler);
103 if (Options.HandleXfsz)
104 SetSigaction(SIGXFSZ, FileSizeExceedHandler);
kcc1239a992017-11-09 20:30:19 +0000105 if (Options.HandleUsr1)
106 SetSigaction(SIGUSR1, GracefulExitHandler);
107 if (Options.HandleUsr2)
108 SetSigaction(SIGUSR2, GracefulExitHandler);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000109}
110
111void SleepSeconds(int Seconds) {
112 sleep(Seconds); // Use C API to avoid coverage from instrumented libc++.
113}
114
115unsigned long GetPid() { return (unsigned long)getpid(); }
116
117size_t GetPeakRSSMb() {
118 struct rusage usage;
119 if (getrusage(RUSAGE_SELF, &usage))
120 return 0;
vitalybuka5f3206d2018-04-09 22:38:26 +0000121 if (LIBFUZZER_LINUX || LIBFUZZER_FREEBSD || LIBFUZZER_NETBSD ||
122 LIBFUZZER_OPENBSD) {
george.karpenkov29efa6d2017-08-21 23:25:50 +0000123 // ru_maxrss is in KiB
124 return usage.ru_maxrss >> 10;
125 } else if (LIBFUZZER_APPLE) {
126 // ru_maxrss is in bytes
127 return usage.ru_maxrss >> 20;
128 }
129 assert(0 && "GetPeakRSSMb() is not implemented for your platform");
130 return 0;
131}
132
133FILE *OpenProcessPipe(const char *Command, const char *Mode) {
134 return popen(Command, Mode);
135}
136
137const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
138 size_t PattLen) {
139 return memmem(Data, DataLen, Patt, PattLen);
140}
141
142std::string DisassembleCmd(const std::string &FileName) {
143 return "objdump -d " + FileName;
144}
145
146std::string SearchRegexCmd(const std::string &Regex) {
147 return "grep '" + Regex + "'";
148}
149
150} // namespace fuzzer
151
152#endif // LIBFUZZER_POSIX