| //===- FuzzerUtilPosix.cpp - Misc utils for Posix. ------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // Misc utils implementation using Posix API. |
| //===----------------------------------------------------------------------===// |
| #include "FuzzerDefs.h" |
| #if LIBFUZZER_POSIX |
| #include "FuzzerIO.h" |
| #include "FuzzerInternal.h" |
| #include <cassert> |
| #include <chrono> |
| #include <cstring> |
| #include <errno.h> |
| #include <iomanip> |
| #include <signal.h> |
| #include <stdio.h> |
| #include <sys/resource.h> |
| #include <sys/syscall.h> |
| #include <sys/time.h> |
| #include <sys/types.h> |
| #include <thread> |
| #include <unistd.h> |
| |
| namespace fuzzer { |
| |
| static void AlarmHandler(int, siginfo_t *, void *) { |
| Fuzzer::StaticAlarmCallback(); |
| } |
| |
| static void CrashHandler(int, siginfo_t *, void *) { |
| Fuzzer::StaticCrashSignalCallback(); |
| } |
| |
| static void InterruptHandler(int, siginfo_t *, void *) { |
| Fuzzer::StaticInterruptCallback(); |
| } |
| |
| static void GracefulExitHandler(int, siginfo_t *, void *) { |
| Fuzzer::StaticGracefulExitCallback(); |
| } |
| |
| static void FileSizeExceedHandler(int, siginfo_t *, void *) { |
| Fuzzer::StaticFileSizeExceedCallback(); |
| } |
| |
| static void SetSigaction(int signum, |
| void (*callback)(int, siginfo_t *, void *)) { |
| struct sigaction sigact = {}; |
| if (sigaction(signum, nullptr, &sigact)) { |
| Printf("libFuzzer: sigaction failed with %d\n", errno); |
| exit(1); |
| } |
| if (sigact.sa_flags & SA_SIGINFO) { |
| if (sigact.sa_sigaction) |
| return; |
| } else { |
| if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN && |
| sigact.sa_handler != SIG_ERR) |
| return; |
| } |
| |
| sigact = {}; |
| sigact.sa_sigaction = callback; |
| if (sigaction(signum, &sigact, 0)) { |
| Printf("libFuzzer: sigaction failed with %d\n", errno); |
| exit(1); |
| } |
| } |
| |
| void SetTimer(int Seconds) { |
| struct itimerval T { |
| {Seconds, 0}, { Seconds, 0 } |
| }; |
| if (setitimer(ITIMER_REAL, &T, nullptr)) { |
| Printf("libFuzzer: setitimer failed with %d\n", errno); |
| exit(1); |
| } |
| SetSigaction(SIGALRM, AlarmHandler); |
| } |
| |
| void SetSignalHandler(const FuzzingOptions& Options) { |
| if (Options.UnitTimeoutSec > 0) |
| SetTimer(Options.UnitTimeoutSec / 2 + 1); |
| if (Options.HandleInt) |
| SetSigaction(SIGINT, InterruptHandler); |
| if (Options.HandleTerm) |
| SetSigaction(SIGTERM, InterruptHandler); |
| if (Options.HandleSegv) |
| SetSigaction(SIGSEGV, CrashHandler); |
| if (Options.HandleBus) |
| SetSigaction(SIGBUS, CrashHandler); |
| if (Options.HandleAbrt) |
| SetSigaction(SIGABRT, CrashHandler); |
| if (Options.HandleIll) |
| SetSigaction(SIGILL, CrashHandler); |
| if (Options.HandleFpe) |
| SetSigaction(SIGFPE, CrashHandler); |
| if (Options.HandleXfsz) |
| SetSigaction(SIGXFSZ, FileSizeExceedHandler); |
| if (Options.HandleUsr1) |
| SetSigaction(SIGUSR1, GracefulExitHandler); |
| if (Options.HandleUsr2) |
| SetSigaction(SIGUSR2, GracefulExitHandler); |
| } |
| |
| void SleepSeconds(int Seconds) { |
| sleep(Seconds); // Use C API to avoid coverage from instrumented libc++. |
| } |
| |
| unsigned long GetPid() { return (unsigned long)getpid(); } |
| |
| size_t GetPeakRSSMb() { |
| struct rusage usage; |
| if (getrusage(RUSAGE_SELF, &usage)) |
| return 0; |
| if (LIBFUZZER_LINUX || LIBFUZZER_FREEBSD || LIBFUZZER_NETBSD || |
| LIBFUZZER_OPENBSD) { |
| // ru_maxrss is in KiB |
| return usage.ru_maxrss >> 10; |
| } else if (LIBFUZZER_APPLE) { |
| // ru_maxrss is in bytes |
| return usage.ru_maxrss >> 20; |
| } |
| assert(0 && "GetPeakRSSMb() is not implemented for your platform"); |
| return 0; |
| } |
| |
| FILE *OpenProcessPipe(const char *Command, const char *Mode) { |
| return popen(Command, Mode); |
| } |
| |
| const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt, |
| size_t PattLen) { |
| return memmem(Data, DataLen, Patt, PattLen); |
| } |
| |
| std::string DisassembleCmd(const std::string &FileName) { |
| return "objdump -d " + FileName; |
| } |
| |
| std::string SearchRegexCmd(const std::string &Regex) { |
| return "grep '" + Regex + "'"; |
| } |
| |
| } // namespace fuzzer |
| |
| #endif // LIBFUZZER_POSIX |