Commit a1849a11 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Limit the number of reads in the gzip fuzzer.

It already has two timeout mitigations - one on the size of output, one
on the size of the input, but they're not enough. This CL replaces them
with a single limit on the number of reads, which should hopefully mean
we don't have to invest any more time dealing with silly timeouts.

Bug: 1006309
Change-Id: I50c6c52b26c43826efd5071ce0b345cd9782ca84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1912142Reviewed-by: default avatarDavid Benjamin <davidben@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714694}
parent 695d852d
......@@ -18,19 +18,15 @@
//
// |data| is used to create a FuzzedSourceStream.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Bound the input to 256 KiB. If the input is divided into one-byte chunks,
// the fuzzer may time out. See https://crbug.com/1014767.
size = std::min(size, size_t(256 * 1024));
net::TestCompletionCallback callback;
FuzzedDataProvider data_provider(data, size);
auto fuzzed_source_stream =
std::make_unique<net::FuzzedSourceStream>(&data_provider);
// Gzip has a maximum compression ratio of 1032x. While, strictly speaking,
// linear, this means the fuzzer will often get stuck. Bound the output. See
// https://crbug.com/921075.
size_t max_output = 512 * 1024;
// Bound the total number of reads. Gzip has a maximum compression ratio of
// 1032x. While, strictly speaking, linear, this means the fuzzer will often
// get stuck. Bound the number of reads rather than the size of the output
// because lots of 1-byte chunks is also a problem.
const size_t kMaxReads = 10 * 1024;
const net::SourceStream::SourceType kGzipTypes[] = {
net::SourceStream::TYPE_GZIP, net::SourceStream::TYPE_DEFLATE};
......@@ -38,20 +34,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
data_provider.PickValueInArray(kGzipTypes);
std::unique_ptr<net::GzipSourceStream> gzip_stream =
net::GzipSourceStream::Create(std::move(fuzzed_source_stream), type);
size_t bytes_read = 0;
while (true) {
size_t num_reads = 0;
while (num_reads < kMaxReads) {
scoped_refptr<net::IOBufferWithSize> io_buffer =
base::MakeRefCounted<net::IOBufferWithSize>(64);
net::TestCompletionCallback callback;
int result = gzip_stream->Read(io_buffer.get(), io_buffer->size(),
callback.callback());
++num_reads;
// Releasing the pointer to IOBuffer immediately is more likely to lead to a
// use-after-free.
io_buffer = nullptr;
result = callback.GetResult(result);
if (result <= 0)
break;
bytes_read += static_cast<size_t>(result);
if (bytes_read >= max_output)
if (callback.GetResult(result) <= 0)
break;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment