From 88202178628dd385a1435de344bc449b6ea32d47 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Tue, 19 Jan 2016 20:33:57 +0000 Subject: [PATCH] [libFuzzer] use std::mt19937 for generating random numbers by default. Fix MyStoll to handle negative values. Use std::any_of instead of std::find_if llvm-svn: 258178 --- lib/Fuzzer/FuzzerDriver.cpp | 14 ++++++++++---- lib/Fuzzer/FuzzerInterface.cpp | 14 ++++++++++++++ lib/Fuzzer/FuzzerInterface.h | 15 ++++++++++++++- lib/Fuzzer/FuzzerMutate.cpp | 5 ++--- lib/Fuzzer/test/fuzzer.test | 3 +++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index f3743ffb8e4..33bdcfb7320 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -100,13 +100,18 @@ static const char *FlagValue(const char *Param, const char *Name) { // Avoid calling stol as it triggers a bug in clang/glibc build. static long MyStol(const char *Str) { long Res = 0; + long Sign = 1; + if (*Str == '-') { + Str++; + Sign = -1; + } for (size_t i = 0; Str[i]; i++) { char Ch = Str[i]; if (Ch < '0' || Ch > '9') return Res; Res = Res * 10 + (Ch - '0'); } - return Res; + return Res * Sign; } static bool ParseOneFlag(const char *Param) { @@ -223,7 +228,7 @@ int RunOneTest(Fuzzer *F, const char *InputFilePath) { } int FuzzerDriver(int argc, char **argv, UserCallback Callback) { - FuzzerRandomLibc Rand(0); + FuzzerRandom_mt19937 Rand(0); SimpleUserSuppliedFuzzer SUSF(&Rand, Callback); return FuzzerDriver(argc, argv, SUSF); } @@ -234,7 +239,7 @@ int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) { } int FuzzerDriver(const std::vector &Args, UserCallback Callback) { - FuzzerRandomLibc Rand(0); + FuzzerRandom_mt19937 Rand(0); SimpleUserSuppliedFuzzer SUSF(&Rand, Callback); return FuzzerDriver(Args, SUSF); } @@ -326,7 +331,8 @@ int FuzzerDriver(const std::vector &Args, unsigned Seed = Flags.seed; // Initialize Seed. if (Seed == 0) - Seed = time(0) * 10000 + getpid(); + Seed = (std::chrono::system_clock::now().time_since_epoch().count() << 10) + + getpid(); if (Flags.verbosity) Printf("Seed: %u\n", Seed); USF.GetRand().ResetSeed(Seed); diff --git a/lib/Fuzzer/FuzzerInterface.cpp b/lib/Fuzzer/FuzzerInterface.cpp index 76623ecf7d4..149ec66e5d5 100644 --- a/lib/Fuzzer/FuzzerInterface.cpp +++ b/lib/Fuzzer/FuzzerInterface.cpp @@ -12,6 +12,7 @@ #include "FuzzerInterface.h" #include "FuzzerInternal.h" +#include namespace fuzzer { @@ -19,6 +20,19 @@ void FuzzerRandomLibc::ResetSeed(unsigned int seed) { srand(seed); } size_t FuzzerRandomLibc::Rand() { return rand(); } +struct FuzzerRandom_mt19937::Impl : public std::mt19937 { + Impl(unsigned seed) : std::mt19937(seed) {} +}; + +void FuzzerRandom_mt19937::ResetSeed(unsigned int seed) { + delete R; + R = new Impl(seed); +} + +FuzzerRandom_mt19937::~FuzzerRandom_mt19937() { delete R; } + +size_t FuzzerRandom_mt19937::Rand() { return (*R)(); } + UserSuppliedFuzzer::UserSuppliedFuzzer(FuzzerRandomBase *Rand) : Rand(Rand), MD(new MutationDispatcher(*Rand)) {} diff --git a/lib/Fuzzer/FuzzerInterface.h b/lib/Fuzzer/FuzzerInterface.h index b64dff8fe43..64b8f868f65 100644 --- a/lib/Fuzzer/FuzzerInterface.h +++ b/lib/Fuzzer/FuzzerInterface.h @@ -68,14 +68,27 @@ class FuzzerRandomBase { bool RandBool() { return Rand() % 2; } }; +// Using libc's stand/rand. class FuzzerRandomLibc : public FuzzerRandomBase { public: FuzzerRandomLibc(unsigned int seed) { ResetSeed(seed); } void ResetSeed(unsigned int seed) override; - ~FuzzerRandomLibc() override {} + ~FuzzerRandomLibc() override {}; size_t Rand() override; }; +// Using std::mt19937 +class FuzzerRandom_mt19937 : public FuzzerRandomBase { + public: + FuzzerRandom_mt19937(unsigned int seed) { ResetSeed(seed); } + void ResetSeed(unsigned int seed) override; + ~FuzzerRandom_mt19937() override; + size_t Rand() override; + private: + struct Impl; + Impl *R = nullptr; +}; + // For backward compatibility only, deprecated. size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, FuzzerRandomBase &Rand); diff --git a/lib/Fuzzer/FuzzerMutate.cpp b/lib/Fuzzer/FuzzerMutate.cpp index 6e3e6b001cd..69680c8a1a4 100644 --- a/lib/Fuzzer/FuzzerMutate.cpp +++ b/lib/Fuzzer/FuzzerMutate.cpp @@ -29,9 +29,8 @@ struct DictionaryEntry { struct Dictionary : public std::vector{ bool ContainsWord(const Word &W) const { - return end() != - std::find_if(begin(), end(), - [&](const DictionaryEntry &DE) { return DE.W == W; }); + return std::any_of(begin(), end(), + [&](const DictionaryEntry &DE) { return DE.W == W; }); } }; diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test index c8a17f53880..5754058cf69 100644 --- a/lib/Fuzzer/test/fuzzer.test +++ b/lib/Fuzzer/test/fuzzer.test @@ -39,3 +39,6 @@ OOB: AddressSanitizer: heap-buffer-overflow OOB: is located 0 bytes to the right of 3-byte region RUN: not LLVMFuzzer-InitializeTest 2>&1 | FileCheck %s + +RUN: LLVMFuzzer-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE +CHECK_SEED_MINUS_ONE: Seed: 4294967295