[llvm] r257701 - [libFuzzer] make sure we find buffer overflow in the input buffer. Previously, re-using the same vector object was hiding buffer overflows (unless we used annotated vector)
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 13 15:02:30 PST 2016
Author: kcc
Date: Wed Jan 13 17:02:30 2016
New Revision: 257701
URL: http://llvm.org/viewvc/llvm-project?rev=257701&view=rev
Log:
[libFuzzer] make sure we find buffer overflow in the input buffer. Previously, re-using the same vector object was hiding buffer overflows (unless we used annotated vector)
Added:
llvm/trunk/lib/Fuzzer/test/BufferOverflowOnInput.cpp
Modified:
llvm/trunk/lib/Fuzzer/FuzzerInternal.h
llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
llvm/trunk/lib/Fuzzer/test/fuzzer.test
Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=257701&r1=257700&r2=257701&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Wed Jan 13 17:02:30 2016
@@ -106,6 +106,7 @@ class Fuzzer {
void Drill();
void ShuffleAndMinimize();
void InitializeTraceState();
+ void AssignTaintLabels(uint8_t *Data, size_t Size);
size_t CorpusSize() const { return Corpus.size(); }
void ReadDir(const std::string &Path, long *Epoch) {
Printf("Loading corpus: %s\n", Path.c_str());
Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=257701&r1=257700&r2=257701&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Wed Jan 13 17:02:30 2016
@@ -11,6 +11,8 @@
#include "FuzzerInternal.h"
#include <algorithm>
+#include <cstring>
+#include <memory>
#if defined(__has_include)
# if __has_include(<sanitizer/coverage_interface.h>)
@@ -240,11 +242,12 @@ void Fuzzer::RunOneAndUpdateCorpus(Unit
}
void Fuzzer::ExecuteCallback(const Unit &U) {
- const uint8_t *Data = U.data();
- uint8_t EmptyData;
- if (!Data)
- Data = &EmptyData;
- int Res = USF.TargetFunction(Data, U.size());
+ // We copy the contents of Unit into a separate heap buffer
+ // so that we reliably find buffer overflows in it.
+ std::unique_ptr<uint8_t[]> Data(new uint8_t[U.size()]);
+ memcpy(Data.get(), U.data(), U.size());
+ AssignTaintLabels(Data.get(), U.size());
+ int Res = USF.TargetFunction(Data.get(), U.size());
(void)Res;
assert(Res == 0);
}
Modified: llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp?rev=257701&r1=257700&r2=257701&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp Wed Jan 13 17:02:30 2016
@@ -451,9 +451,6 @@ static TraceState *TS;
void Fuzzer::StartTraceRecording() {
if (!TS) return;
- if (ReallyHaveDFSan())
- for (size_t i = 0; i < static_cast<size_t>(Options.MaxLen); i++)
- dfsan_set_label(i + 1, &CurrentUnit[i], 1);
TS->StartTraceRecording();
}
@@ -462,18 +459,24 @@ void Fuzzer::StopTraceRecording() {
TS->StopTraceRecording();
}
+void Fuzzer::AssignTaintLabels(uint8_t *Data, size_t Size) {
+ if (!Options.UseTraces) return;
+ if (!ReallyHaveDFSan()) return;
+ for (size_t i = 0; i < Size; i++)
+ dfsan_set_label(i + 1, &Data[i], 1);
+}
+
void Fuzzer::InitializeTraceState() {
if (!Options.UseTraces) return;
TS = new TraceState(USF, Options, CurrentUnit);
- CurrentUnit.resize(Options.MaxLen);
- // The rest really requires DFSan.
- if (!ReallyHaveDFSan()) return;
- for (size_t i = 0; i < static_cast<size_t>(Options.MaxLen); i++) {
- dfsan_label L = dfsan_create_label("input", (void*)(i + 1));
- // We assume that no one else has called dfsan_create_label before.
- if (L != i + 1) {
- Printf("DFSan labels are not starting from 1, exiting\n");
- exit(1);
+ if (ReallyHaveDFSan()) {
+ for (size_t i = 0; i < static_cast<size_t>(Options.MaxLen); i++) {
+ dfsan_label L = dfsan_create_label("input", (void *)(i + 1));
+ // We assume that no one else has called dfsan_create_label before.
+ if (L != i + 1) {
+ Printf("DFSan labels are not starting from 1, exiting\n");
+ exit(1);
+ }
}
}
}
Added: llvm/trunk/lib/Fuzzer/test/BufferOverflowOnInput.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/BufferOverflowOnInput.cpp?rev=257701&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/BufferOverflowOnInput.cpp (added)
+++ llvm/trunk/lib/Fuzzer/test/BufferOverflowOnInput.cpp Wed Jan 13 17:02:30 2016
@@ -0,0 +1,20 @@
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <assert.h>
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <iostream>
+
+static volatile bool SeedLargeBuffer;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size >= 4)
+ SeedLargeBuffer = true;
+ if (Size == 3 && SeedLargeBuffer && Data[3]) {
+ std::cout << "Woops, reading Data[3] w/o crashing\n";
+ exit(1);
+ }
+ return 0;
+}
+
Modified: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CMakeLists.txt?rev=257701&r1=257700&r2=257701&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt Wed Jan 13 17:02:30 2016
@@ -13,6 +13,7 @@ set(DFSanTests
)
set(Tests
+ BufferOverflowOnInput
CallerCalleeTest
CounterTest
FourIndependentBranchesTest
Modified: llvm/trunk/lib/Fuzzer/test/fuzzer.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer.test?rev=257701&r1=257700&r2=257701&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer.test Wed Jan 13 17:02:30 2016
@@ -34,3 +34,6 @@ PCS:{{^0x[a-f0-9]+}}
PCS:NEW
PCS:BINGO
+RUN: not LLVMFuzzer-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB
+OOB: AddressSanitizer: heap-buffer-overflow
+OOB: is located 0 bytes to the right of 3-byte region
More information about the llvm-commits
mailing list