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 FileSizeExceedHandler(int, siginfo_t *, void *) { 44 Fuzzer::StaticFileSizeExceedCallback(); 45 } 46 47 static 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 71 void 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 82 void 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 103 void SleepSeconds(int Seconds) { 104 sleep(Seconds); // Use C API to avoid coverage from instrumented libc++. 105 } 106 107 unsigned long GetPid() { return (unsigned long)getpid(); } 108 109 size_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 124 FILE *OpenProcessPipe(const char *Command, const char *Mode) { 125 return popen(Command, Mode); 126 } 127 128 const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt, 129 size_t PattLen) { 130 return memmem(Data, DataLen, Patt, PattLen); 131 } 132 133 std::string DisassembleCmd(const std::string &FileName) { 134 return "objdump -d " + FileName; 135 } 136 137 std::string SearchRegexCmd(const std::string &Regex) { 138 return "grep '" + Regex + "'"; 139 } 140 141 } // namespace fuzzer 142 143 #endif // LIBFUZZER_POSIX 144