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