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