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