Skip to content

Commit

Permalink
Use binary write mode in WriteToFile function to avoid appended \r ch…
Browse files Browse the repository at this point in the history
…aracters on Windows

Summary:
When using libfuzzer on Windows, in the contents of a crash sample, bytes that can be mistaken for a \n are replaced by a \r\n sequence. As a consequence, crashes are not reproducible. This patch will open files in binary mode to fix this issue. The patch does not affect POSIX systems.

Patch by tuktuk

Reviewers: kcc, vitalybuka

Reviewed By: vitalybuka

Subscribers: dexonsmith, jdoerfert, llvm-commits, #sanitizers

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D60008

llvm-svn: 357807
  • Loading branch information
vitalybuka committed Apr 5, 2019
1 parent 883ab23 commit 3db6ad2
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler-rt/lib/fuzzer/FuzzerIO.cpp
Expand Up @@ -62,7 +62,7 @@ void CopyFileToErr(const std::string &Path) {

void WriteToFile(const Unit &U, const std::string &Path) {
// Use raw C interface because this function may be called from a sig handler.
FILE *Out = fopen(Path.c_str(), "w");
FILE *Out = fopen(Path.c_str(), "wb");
if (!Out) return;
fwrite(U.data(), sizeof(U[0]), U.size(), Out);
fclose(Out);
Expand Down
24 changes: 24 additions & 0 deletions compiler-rt/test/fuzzer/ReloadTest.cpp
@@ -0,0 +1,24 @@
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Test that fuzzer we can reload artifacts with any bytes inside.
#include <algorithm>
#include <cstdint>
#include <numeric>
#include <set>
#include <stdio.h>

extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
size_t MaxSize, unsigned int Seed) {
std::srand(Seed);
std::generate(Data, Data + MaxSize, std::rand);
return MaxSize;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size > 5000 && std::set<uint8_t>(Data, Data + Size).size() > 255 &&
(uint8_t)std::accumulate(Data, Data + Size, uint8_t(Size)) == 0)
__builtin_trap();
return 0;
}
13 changes: 13 additions & 0 deletions compiler-rt/test/fuzzer/reload.test
@@ -0,0 +1,13 @@
RUN: %cpp_compiler %S/ReloadTest.cpp -o %t-ReloadTest
RUN: not %run %t-ReloadTest -max_len=10000 -seed=1 -timeout=15 -len_control=0 -exact_artifact_path=%t.crash 2>&1 | FileCheck %s

CHECK: Test unit written to {{.*}}reload.test.tmp.crash

RUN: not %run %t-ReloadTest %t.crash 2>&1 | FileCheck %s --check-prefix=ARTIFACT

ARTIFACT: Running: {{.*}}reload.test.tmp.crash
ARTIFACT: ERROR: libFuzzer: deadly signal

# Sanity check that altered artifact is not going to crash
RUN: echo z >> %t.crash
RUN: %run %t-ReloadTest %t.crash

0 comments on commit 3db6ad2

Please sign in to comment.