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