blob: e8d48dc81a3b87cd09bda334785371d7e4a8d784 [file] [log] [blame]
Zachary Turner6fa57ad2016-12-02 23:02:01 +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//===----------------------------------------------------------------------===//
Zachary Turner6fa57ad2016-12-02 23:02:01 +000011#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
Kostya Serebryany4aa05902017-01-05 22:05:47 +000044static void FileSizeExceedHandler(int, siginfo_t *, void *) {
45 Fuzzer::StaticFileSizeExceedCallback();
46}
47
Zachary Turner6fa57ad2016-12-02 23:02:01 +000048static void SetSigaction(int signum,
49 void (*callback)(int, siginfo_t *, void *)) {
50 struct sigaction sigact;
51 memset(&sigact, 0, sizeof(sigact));
52 sigact.sa_sigaction = callback;
53 if (sigaction(signum, &sigact, 0)) {
54 Printf("libFuzzer: sigaction failed with %d\n", errno);
55 exit(1);
56 }
57}
58
59void SetTimer(int Seconds) {
60 struct itimerval T {
61 {Seconds, 0}, { Seconds, 0 }
62 };
63 if (setitimer(ITIMER_REAL, &T, nullptr)) {
64 Printf("libFuzzer: setitimer failed with %d\n", errno);
65 exit(1);
66 }
67 SetSigaction(SIGALRM, AlarmHandler);
68}
69
Marcos Pividoric59b6922016-12-13 17:45:20 +000070void SetSignalHandler(const FuzzingOptions& Options) {
71 if (Options.UnitTimeoutSec > 0)
72 SetTimer(Options.UnitTimeoutSec / 2 + 1);
73 if (Options.HandleInt)
74 SetSigaction(SIGINT, InterruptHandler);
75 if (Options.HandleTerm)
76 SetSigaction(SIGTERM, InterruptHandler);
77 if (Options.HandleSegv)
78 SetSigaction(SIGSEGV, CrashHandler);
79 if (Options.HandleBus)
80 SetSigaction(SIGBUS, CrashHandler);
81 if (Options.HandleAbrt)
82 SetSigaction(SIGABRT, CrashHandler);
83 if (Options.HandleIll)
84 SetSigaction(SIGILL, CrashHandler);
85 if (Options.HandleFpe)
86 SetSigaction(SIGFPE, CrashHandler);
Kostya Serebryany4aa05902017-01-05 22:05:47 +000087 if (Options.HandleXfsz)
88 SetSigaction(SIGXFSZ, FileSizeExceedHandler);
Marcos Pividoric59b6922016-12-13 17:45:20 +000089}
Zachary Turner6fa57ad2016-12-02 23:02:01 +000090
91void SleepSeconds(int Seconds) {
92 sleep(Seconds); // Use C API to avoid coverage from instrumented libc++.
93}
94
Marcos Pividori463f8bd2016-12-13 17:45:44 +000095unsigned long GetPid() { return (unsigned long)getpid(); }
Zachary Turner6fa57ad2016-12-02 23:02:01 +000096
97size_t GetPeakRSSMb() {
98 struct rusage usage;
99 if (getrusage(RUSAGE_SELF, &usage))
100 return 0;
101 if (LIBFUZZER_LINUX) {
102 // ru_maxrss is in KiB
103 return usage.ru_maxrss >> 10;
104 } else if (LIBFUZZER_APPLE) {
105 // ru_maxrss is in bytes
106 return usage.ru_maxrss >> 20;
107 }
108 assert(0 && "GetPeakRSSMb() is not implemented for your platform");
109 return 0;
110}
111
112FILE *OpenProcessPipe(const char *Command, const char *Mode) {
113 return popen(Command, Mode);
114}
115
116const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
117 size_t PattLen) {
118 return memmem(Data, DataLen, Patt, PattLen);
119}
120
Marcos Pividori178fe582016-12-13 17:46:11 +0000121} // namespace fuzzer
122
Zachary Turner6fa57ad2016-12-02 23:02:01 +0000123#endif // LIBFUZZER_POSIX