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