Skip to content

Commit

Permalink
[libFuzzer] extend -rss_limit_mb to crash instantly on a single mallo…
Browse files Browse the repository at this point in the history
…c that exceeds the limit

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288281 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
kcc committed Nov 30, 2016
1 parent bcdc161 commit b89fb12
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 4 deletions.
2 changes: 2 additions & 0 deletions lib/Fuzzer/FuzzerInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class Fuzzer {
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
bool DuringInitialCorpusExecution);

void HandleMalloc(size_t Size);

private:
void AlarmCallback();
void CrashCallback();
Expand Down
16 changes: 16 additions & 0 deletions lib/Fuzzer/FuzzerLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ static MallocFreeTracer AllocTracer;

void MallocHook(const volatile void *ptr, size_t size) {
size_t N = AllocTracer.Mallocs++;
F->HandleMalloc(size);
if (int TraceLevel = AllocTracer.TraceLevel) {
Printf("MALLOC[%zd] %p %zd\n", N, ptr, size);
if (TraceLevel >= 2 && EF)
Expand All @@ -155,6 +156,21 @@ void FreeHook(const volatile void *ptr) {
}
}

// Crash on a single malloc that exceeds the rss limit.
void Fuzzer::HandleMalloc(size_t Size) {
if ((Size >> 20) < (size_t)Options.RssLimitMb)
return;
Printf("==%d== ERROR: libFuzzer: out-of-memory (malloc(%zd))\n", GetPid(),
Size);
Printf(" To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
if (EF->__sanitizer_print_stack_trace)
EF->__sanitizer_print_stack_trace();
DumpCurrentUnit("oom-");
Printf("SUMMARY: libFuzzer: out-of-memory\n");
PrintFinalStats();
_Exit(Options.ErrorExitCode); // Stop right now.
}

Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
FuzzingOptions Options)
: CB(CB), Corpus(Corpus), MD(MD), Options(Options) {
Expand Down
1 change: 1 addition & 0 deletions lib/Fuzzer/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ set(Tests
NthRunCrashTest
OneHugeAllocTest
OutOfMemoryTest
OutOfMemorySingleLargeMallocTest
RepeatedMemcmp
RepeatedBytesTest
SimpleCmpTest
Expand Down
28 changes: 28 additions & 0 deletions lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Tests OOM handling.
#include <assert.h>
#include <cstdint>
#include <cstdlib>
#include <cstddef>
#include <cstring>
#include <iostream>
#include <unistd.h>

static volatile char *SinkPtr;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size > 0 && Data[0] == 'H') {
if (Size > 1 && Data[1] == 'i') {
if (Size > 2 && Data[2] == '!') {
size_t kSize = 0xff000000U;
char *p = new char[kSize];
SinkPtr = p;
delete [] p;
}
}
}
return 0;
}

4 changes: 2 additions & 2 deletions lib/Fuzzer/test/fuzzer-oom-with-profile.test
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
REQUIRES: linux
RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=10 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 10Mb)
RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
CHECK: Live Heap Allocations
CHECK: Test unit written to ./oom-
SUMMARY: libFuzzer: out-of-memory
8 changes: 6 additions & 2 deletions lib/Fuzzer/test/fuzzer-oom.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=10 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 10Mb)
RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
CHECK: Test unit written to ./oom-
SUMMARY: libFuzzer: out-of-memory

RUN: not LLVMFuzzer-OutOfMemorySingleLargeMallocTest 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory (malloc(42{{.*}}))
SINGLE_LARGE_MALLOC: in LLVMFuzzerTestOneInput

0 comments on commit b89fb12

Please sign in to comment.