Skip to content

Commit 90b4d1b

Browse files
author
Roy Sundahl
committed
[fuzzer] Use puts() rather than printf() in CopyFileToErr()
CopyFileToErr() uses Printf("%s", ...) which fails with a negative size on files >2Gb (Its path is through var-args wrappers to an unnecessary "%s" expansion and subject to int overflows) Using puts() in place of printf() bypasses this path and writes the string directly to stderr. This avoids the present loss of data when a crashed worker has generated >2Gb of output. rdar://99384640 Reviewed By: yln, rsundahl Differential Revision: https://reviews.llvm.org/D146189
1 parent 2fe49ea commit 90b4d1b

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

compiler-rt/lib/fuzzer/FuzzerIO.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ std::string FileToString(const std::string &Path) {
6565
}
6666

6767
void CopyFileToErr(const std::string &Path) {
68-
Printf("%s", FileToString(Path).c_str());
68+
Puts(FileToString(Path).c_str());
6969
}
7070

7171
void WriteToFile(const Unit &U, const std::string &Path) {
@@ -151,6 +151,11 @@ void CloseStdout() {
151151
DiscardOutput(1);
152152
}
153153

154+
void Puts(const char *Str) {
155+
fputs(Str, OutputFile);
156+
fflush(OutputFile);
157+
}
158+
154159
void Printf(const char *Fmt, ...) {
155160
va_list ap;
156161
va_start(ap, Fmt);

compiler-rt/lib/fuzzer/FuzzerIO.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void CloseStdout();
5858
FILE *GetOutputFile();
5959
void SetOutputFile(FILE *NewOutputFile);
6060

61+
void Puts(const char *Str);
6162
void Printf(const char *Fmt, ...);
6263
void VPrintf(bool Verbose, const char *Fmt, ...);
6364

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2+
// See https://llvm.org/LICENSE.txt for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
#include <cstddef>
6+
#include <cstdint>
7+
#include <cstdio>
8+
#include <cstdlib>
9+
#include <cstring>
10+
11+
#include "FuzzerIO.h"
12+
13+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
14+
const char *FileName = "big-file.txt";
15+
FILE *f = fopen(FileName, "w");
16+
17+
// This is the biggest file possible unless CopyFileToErr() uses Puts()
18+
fprintf(f, "%2147483646s", "2Gb-2");
19+
20+
// This makes the file too big if CopyFileToErr() uses fprintf("%s", <file>)
21+
fprintf(f, "THIS LINE RESPONSIBLE FOR EXCEEDING 2Gb FILE SIZE\n");
22+
fclose(f);
23+
24+
// Should now because CopyFileToErr() now uses Puts()
25+
fuzzer::CopyFileToErr(FileName);
26+
27+
// File is >2Gb so clean up
28+
remove(FileName);
29+
30+
return 0;
31+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
RUN: %cpp_compiler %S/BigFileCopy.cpp -o %t
2+
RUN: %run %t -runs=1 -rss_limit_mb=4096 2>big-file-out.txt; result=$?
3+
RUN: %run rm -f big-file.txt big-file-out.txt
4+
RUN: %run (exit $result)

0 commit comments

Comments
 (0)