mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 19:59:57 +00:00
[libFuzzer] make sure the input data is not overwritten in the fuzz target (if it is -- report an error)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302494 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3d5255af74
commit
de20a5381a
@ -656,7 +656,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
||||
SMR.WaitClient();
|
||||
size_t Size = SMR.ReadByteArraySize();
|
||||
SMR.WriteByteArray(nullptr, 0);
|
||||
F->RunOne(SMR.GetByteArray(), Size);
|
||||
const Unit tmp(SMR.GetByteArray(), SMR.GetByteArray() + Size);
|
||||
F->RunOne(tmp.data(), tmp.size());
|
||||
SMR.PostServer();
|
||||
}
|
||||
return 0;
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
private:
|
||||
void AlarmCallback();
|
||||
void CrashCallback();
|
||||
void CrashOnOverwrittenData();
|
||||
void InterruptCallback();
|
||||
void MutateAndTestOne();
|
||||
void ReportNewCoverage(InputInfo *II, const Unit &U);
|
||||
|
@ -422,6 +422,24 @@ size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
|
||||
return CurrentUnitSize;
|
||||
}
|
||||
|
||||
void Fuzzer::CrashOnOverwrittenData() {
|
||||
Printf("==%d== ERROR: libFuzzer: fuzz target overwrites it's const input\n",
|
||||
GetPid());
|
||||
DumpCurrentUnit("crash-");
|
||||
Printf("SUMMARY: libFuzzer: out-of-memory\n");
|
||||
_Exit(Options.ErrorExitCode); // Stop right now.
|
||||
}
|
||||
|
||||
// Compare two arrays, but not all bytes if the arrays are large.
|
||||
static bool LooseMemeq(const uint8_t *A, const uint8_t *B, size_t Size) {
|
||||
const size_t Limit = 64;
|
||||
if (Size <= 64)
|
||||
return !memcmp(A, B, Size);
|
||||
// Compare first and last Limit/2 bytes.
|
||||
return !memcmp(A, B, Limit / 2) &&
|
||||
!memcmp(A + Size - Limit / 2, B + Size - Limit / 2, Limit / 2);
|
||||
}
|
||||
|
||||
void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
|
||||
assert(InFuzzingThread());
|
||||
if (SMR.IsClient())
|
||||
@ -443,6 +461,8 @@ void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
|
||||
(void)Res;
|
||||
assert(Res == 0);
|
||||
HasMoreMallocsThanFrees = AllocTracer.Stop();
|
||||
if (!LooseMemeq(DataCopy, Data, Size))
|
||||
CrashOnOverwrittenData();
|
||||
CurrentUnitSize = 0;
|
||||
delete[] DataCopy;
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ set(Tests
|
||||
OneHugeAllocTest
|
||||
OutOfMemoryTest
|
||||
OutOfMemorySingleLargeMallocTest
|
||||
OverwriteInputTest
|
||||
RepeatedMemcmp
|
||||
RepeatedBytesTest
|
||||
SimpleCmpTest
|
||||
|
13
lib/Fuzzer/test/OverwriteInputTest.cpp
Normal file
13
lib/Fuzzer/test/OverwriteInputTest.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
|
||||
// Simple test for a fuzzer. Make sure we abort if Data is overwritten.
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
if (Size)
|
||||
*const_cast<uint8_t*>(Data) = 1;
|
||||
return 0;
|
||||
}
|
||||
|
2
lib/Fuzzer/test/overwrite-input.test
Normal file
2
lib/Fuzzer/test/overwrite-input.test
Normal file
@ -0,0 +1,2 @@
|
||||
RUN: not LLVMFuzzer-OverwriteInputTest 2>&1 | FileCheck %s
|
||||
CHECK: ERROR: libFuzzer: fuzz target overwrites it's const input
|
Loading…
Reference in New Issue
Block a user