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