Commit 3ca20a18 authored by Abhishek Arya's avatar Abhishek Arya Committed by Commit Bot

Create template helper for ConsumeIntegral in fuzzing.

R=ochang@google.com

Bug: 907103
Change-Id: I6a6f7f6eb33574e415d71ee72c35a2eecfa22c87
Reviewed-on: https://chromium-review.googlesource.com/c/1352827Reviewed-by: default avatarEric Roman <eroman@chromium.org>
Reviewed-by: default avatarenne <enne@chromium.org>
Reviewed-by: default avatarAlbert J. Wong <ajwong@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarOliver Chang <ochang@chromium.org>
Reviewed-by: default avatarRyan Hamilton <rch@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Reviewed-by: default avatarMax Moroz <mmoroz@chromium.org>
Commit-Queue: Abhishek Arya <inferno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611800}
parent 7baa885d
......@@ -27,7 +27,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::Pickle pickle(reinterpret_cast<const char*>(data), size);
base::PickleIterator iter(pickle);
for (int i = 0; i < kIterations; i++) {
uint8_t read_type = data_provider.ConsumeUint8();
uint8_t read_type = data_provider.ConsumeIntegral<uint8_t>();
switch (read_type % kReadDataTypes) {
case 0: {
bool result = 0;
......
......@@ -152,39 +152,17 @@ class FuzzedDataProvider {
return ConsumeBytesAsString(remaining_bytes_);
}
// Reads one byte and returns a bool, or false when no data remains.
bool ConsumeBool() { return 1 & ConsumeUint8(); }
// Returns a uint8_t from the input or 0 if nothing remains. This is
// equivalent to ConsumeIntegralInRange<uint8_t>(0, 0xFF).
uint8_t ConsumeUint8() {
return ConsumeIntegralInRange(std::numeric_limits<uint8_t>::min(),
std::numeric_limits<uint8_t>::max());
}
// Returns a uint16_t from the input. If fewer than 2 bytes of data remain
// will fill the most significant bytes with 0. This is equivalent to
// ConsumeIntegralInRange<uint16_t>(0, 0xFFFF).
uint16_t ConsumeUint16() {
return ConsumeIntegralInRange(std::numeric_limits<uint16_t>::min(),
std::numeric_limits<uint16_t>::max());
}
// Returns a uint32_t from the input. If fewer than 4 bytes of data remain
// will fill the most significant bytes with 0. This is equivalent to
// ConsumeIntegralInRange<uint32_t>(0, 0xFFFFFFFF).
uint16_t ConsumeUint32() {
return ConsumeIntegralInRange(std::numeric_limits<uint32_t>::min(),
std::numeric_limits<uint32_t>::max());
// Returns a number in the range [Type's min, Type's max]. The value might
// not be uniformly distributed in the given range. If there's no input data
// left, always returns |min|.
template <typename T>
T ConsumeIntegral() {
return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
}
// Returns a uint64_t from the input. If fewer than 8 bytes of data remain
// will fill the most significant bytes with 0. This is equivalent to
// ConsumeIntegralInRange<uint64_t>(0, 0xFFFFFFFFFFFFFFFF).
uint16_t ConsumeUint64() {
return ConsumeIntegralInRange(std::numeric_limits<uint64_t>::min(),
std::numeric_limits<uint64_t>::max());
}
// Reads one byte and returns a bool, or false when no data remains.
bool ConsumeBool() { return 1 & ConsumeIntegral<uint8_t>(); }
// Returns a value from |array|, consuming as many bytes as needed to do so.
// |array| must be a fixed-size array.
......
......@@ -21,15 +21,16 @@ void AddHitTestRegion(base::FuzzedDataProvider* fuzz,
constexpr uint32_t kMaxDepthAllowed = 25;
if (fuzz->remaining_bytes() < sizeof(viz::AggregatedHitTestRegion))
return;
viz::FrameSinkId frame_sink_id(fuzz->ConsumeUint32(), fuzz->ConsumeUint32());
uint32_t flags = fuzz->ConsumeUint32();
viz::FrameSinkId frame_sink_id(fuzz->ConsumeIntegral<uint32_t>(),
fuzz->ConsumeIntegral<uint32_t>());
uint32_t flags = fuzz->ConsumeIntegral<uint32_t>();
// The reasons' value is kNotAsyncHitTest if the flag's value is kHitTestAsk.
uint32_t reasons = (flags & viz::HitTestRegionFlags::kHitTestAsk)
? fuzz->ConsumeIntegralInRange<uint32_t>(
1, std::numeric_limits<uint32_t>::max())
: viz::AsyncHitTestReasons::kNotAsyncHitTest;
gfx::Rect rect(fuzz->ConsumeUint8(), fuzz->ConsumeUint8(),
fuzz->ConsumeUint16(), fuzz->ConsumeUint16());
gfx::Rect rect(fuzz->ConsumeIntegral<int>(), fuzz->ConsumeIntegral<int>(),
fuzz->ConsumeIntegral<int>(), fuzz->ConsumeIntegral<int>());
int32_t child_count =
depth < kMaxDepthAllowed ? fuzz->ConsumeIntegralInRange(0, 10) : 0;
gfx::Transform transform;
......
......@@ -62,14 +62,14 @@ void AddHitTestRegion(base::FuzzedDataProvider* fuzz,
return;
viz::HitTestRegion hit_test_region;
hit_test_region.flags = fuzz->ConsumeUint16();
hit_test_region.flags = fuzz->ConsumeIntegral<uint32_t>();
if (fuzz->ConsumeBool())
hit_test_region.flags |= viz::HitTestRegionFlags::kHitTestChildSurface;
hit_test_region.frame_sink_id =
viz::FrameSinkId(fuzz->ConsumeUint8(), fuzz->ConsumeUint8());
hit_test_region.frame_sink_id = viz::FrameSinkId(
fuzz->ConsumeIntegral<uint32_t>(), fuzz->ConsumeIntegral<uint32_t>());
hit_test_region.rect =
gfx::Rect(fuzz->ConsumeUint8(), fuzz->ConsumeUint8(),
fuzz->ConsumeUint16(), fuzz->ConsumeUint16());
gfx::Rect(fuzz->ConsumeIntegral<int>(), fuzz->ConsumeIntegral<int>(),
fuzz->ConsumeIntegral<int>(), fuzz->ConsumeIntegral<int>());
hit_test_region.transform = GetNextTransform(fuzz);
if (fuzz->ConsumeBool() &&
......@@ -112,16 +112,16 @@ void SubmitHitTestRegionList(
base::Optional<viz::HitTestRegionList> hit_test_region_list;
if (fuzz->ConsumeBool()) {
hit_test_region_list.emplace();
hit_test_region_list->flags = fuzz->ConsumeUint16();
hit_test_region_list->flags = fuzz->ConsumeIntegral<uint32_t>();
if (fuzz->ConsumeBool())
hit_test_region_list->flags |=
viz::HitTestRegionFlags::kHitTestChildSurface;
hit_test_region_list->bounds =
gfx::Rect(fuzz->ConsumeUint8(), fuzz->ConsumeUint8(),
fuzz->ConsumeUint16(), fuzz->ConsumeUint16());
gfx::Rect(fuzz->ConsumeIntegral<int>(), fuzz->ConsumeIntegral<int>(),
fuzz->ConsumeIntegral<int>(), fuzz->ConsumeIntegral<int>());
hit_test_region_list->transform = GetNextTransform(fuzz);
uint32_t child_count = fuzz->ConsumeUint16();
uint32_t child_count = fuzz->ConsumeIntegral<uint32_t>();
AddHitTestRegion(fuzz, &hit_test_region_list->regions, child_count,
delegate, frame_sink_manager, surface_id, depth + 1);
}
......
......@@ -15,7 +15,9 @@
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fuzzed_data(data, size);
size_t first_part_size = fuzzed_data.ConsumeUint16();
// Intentionally using uint16_t here to avoid empty |second_part|.
size_t first_part_size = fuzzed_data.ConsumeIntegral<uint16_t>();
std::vector<uint8_t> first_part = fuzzed_data.ConsumeBytes(first_part_size);
std::vector<uint8_t> second_part = fuzzed_data.ConsumeRemainingBytes();
......
......@@ -15,7 +15,9 @@
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fuzzed_data(data, size);
size_t first_part_size = fuzzed_data.ConsumeUint16();
// Intentionally using uint16_t here to avoid empty |second_part|.
size_t first_part_size = fuzzed_data.ConsumeIntegral<uint16_t>();
std::vector<uint8_t> first_part = fuzzed_data.ConsumeBytes(first_part_size);
std::vector<uint8_t> second_part = fuzzed_data.ConsumeRemainingBytes();
......
......@@ -30,27 +30,35 @@ namespace {
// Returns a fuzzed non-zero port number.
uint16_t FuzzPort(base::FuzzedDataProvider* data_provider) {
return data_provider->ConsumeUint16();
return data_provider->ConsumeIntegral<uint16_t>();
}
// Returns a fuzzed IPv4 address. Can return invalid / reserved addresses.
IPAddress FuzzIPv4Address(base::FuzzedDataProvider* data_provider) {
return IPAddress(data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(),
data_provider->ConsumeUint8());
return IPAddress(data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>());
}
// Returns a fuzzed IPv6 address. Can return invalid / reserved addresses.
IPAddress FuzzIPv6Address(base::FuzzedDataProvider* data_provider) {
return IPAddress(data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
data_provider->ConsumeUint8(),
data_provider->ConsumeUint8());
return IPAddress(data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>(),
data_provider->ConsumeIntegral<uint8_t>());
}
// Returns a fuzzed address, which can be either IPv4 or IPv6. Can return
......@@ -96,8 +104,8 @@ class FuzzedHostResolverProc : public HostResolverProc {
// generally before IPv4 ones.
if (address_family == ADDRESS_FAMILY_UNSPECIFIED ||
address_family == ADDRESS_FAMILY_IPV6) {
size_t num_ipv6_addresses = data_provider_->ConsumeUint8();
for (size_t i = 0; i < num_ipv6_addresses; ++i) {
uint8_t num_ipv6_addresses = data_provider_->ConsumeIntegral<uint8_t>();
for (uint8_t i = 0; i < num_ipv6_addresses; ++i) {
result.push_back(
net::IPEndPoint(FuzzIPv6Address(data_provider_.get()), 0));
}
......@@ -105,8 +113,8 @@ class FuzzedHostResolverProc : public HostResolverProc {
if (address_family == ADDRESS_FAMILY_UNSPECIFIED ||
address_family == ADDRESS_FAMILY_IPV4) {
size_t num_ipv4_addresses = data_provider_->ConsumeUint8();
for (size_t i = 0; i < num_ipv4_addresses; ++i) {
uint8_t num_ipv4_addresses = data_provider_->ConsumeIntegral<uint8_t>();
for (uint8_t i = 0; i < num_ipv4_addresses; ++i) {
result.push_back(
net::IPEndPoint(FuzzIPv4Address(data_provider_.get()), 0));
}
......@@ -191,7 +199,7 @@ void FuzzedHostResolver::SetDnsClientEnabled(bool enabled) {
net::DnsHosts hosts;
// Fuzz hosts file.
uint8_t num_hosts_entries = data_provider_->ConsumeUint8();
uint8_t num_hosts_entries = data_provider_->ConsumeIntegral<uint8_t>();
for (uint8_t i = 0; i < num_hosts_entries; ++i) {
const char* kHostnames[] = {"foo", "foo.com", "a.foo.com",
"bar", "localhost", "localhost6"};
......
......@@ -24,7 +24,7 @@ base::string16 ConsumeRandomLengthString16(
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fdp(data, size);
bool is_v2 = fdp.ConsumeBool();
uint64_t client_time = fdp.ConsumeUint64();
uint64_t client_time = fdp.ConsumeIntegral<uint64_t>();
net::ntlm::NtlmClient client((net::ntlm::NtlmFeatures(is_v2)));
// Generate the input strings and challenge message. The strings will have a
......
......@@ -21,7 +21,7 @@ class WaitTillHttpCloseDelegate : public net::HttpServer::Delegate {
: server_(nullptr),
data_provider_(data_provider),
done_closure_(done_closure),
action_flags_(data_provider_->ConsumeUint8()) {}
action_flags_(data_provider_->ConsumeIntegral<uint8_t>()) {}
void set_server(net::HttpServer* server) { server_ = server; }
......
......@@ -119,7 +119,8 @@ int FuzzedSocket::Write(
num_async_reads_and_writes_ += static_cast<int>(!sync);
result = data_provider_->ConsumeUint8();
// Intentionally using smaller |result| size here.
result = data_provider_->ConsumeIntegralInRange<int>(0, 0xFF);
if (result > buf_len)
result = buf_len;
if (result == 0) {
......
......@@ -25,7 +25,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Build test header list.
spdy::SpdyHeaderBlock header_list;
uint8_t header_count = provider.ConsumeUint8();
uint8_t header_count = provider.ConsumeIntegral<uint8_t>();
for (uint8_t header_index = 0; header_index < header_count; ++header_index) {
if (provider.remaining_bytes() == 0) {
// Do not add more headers if there is no more fuzzer data.
......@@ -34,7 +34,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
QuicString name;
QuicString value;
switch (provider.ConsumeUint8()) {
switch (provider.ConsumeIntegral<uint8_t>()) {
case 0:
// Static table entry with no header value.
name = ":authority";
......
......@@ -12,7 +12,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string uri_template = fuzzed_data.ConsumeRandomLengthString(256);
// Construct a map containing variable names and corresponding values.
std::unordered_map<std::string, std::string> parameters;
uint8_t num_vars(fuzzed_data.ConsumeUint8());
uint8_t num_vars(fuzzed_data.ConsumeIntegral<uint8_t>());
for (uint8_t i = 0; i < num_vars; i++) {
parameters.emplace(fuzzed_data.ConsumeRandomLengthString(10),
fuzzed_data.ConsumeRandomLengthString(10));
......
......@@ -74,7 +74,7 @@ class WebSocketFuzzedStream final : public WebSocketStream {
auto frame = std::make_unique<WebSocketFrame>(opcode);
// Bad news: ConsumeBool actually consumes a whole byte per call, so do
// something hacky to conserve precious bits.
uint8_t flags = fuzzed_data_provider_->ConsumeUint8();
uint8_t flags = fuzzed_data_provider_->ConsumeIntegral<uint8_t>();
frame->header.final = flags & 0x1;
frame->header.reserved1 = (flags >> 1) & 0x1;
frame->header.reserved2 = (flags >> 2) & 0x1;
......@@ -95,10 +95,10 @@ class WebSocketFuzzedStream final : public WebSocketStream {
void WebSocketDeflateStreamFuzz(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fuzzed_data_provider(data, size);
uint8_t flags = fuzzed_data_provider.ConsumeUint8();
uint8_t flags = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
bool server_no_context_takeover = flags & 0x1;
bool client_no_context_takeover = (flags >> 1) & 0x1;
uint8_t window_bits = fuzzed_data_provider.ConsumeUint8();
uint8_t window_bits = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
int server_max_window_bits = (window_bits & 0x7) + 8;
int client_max_window_bits = ((window_bits >> 3) & 0x7) + 8;
// WebSocketDeflateStream needs to be constructed on each call because it
......
......@@ -39,6 +39,14 @@ class FuzzedDataProvider {
return provider_.ConsumeIntegralInRange<T>(min, max);
}
// Returns a number in the range [Type's min, Type's max]. The value might
// not be uniformly distributed in the given range. If there's no input data
// left, always returns |min|.
template <typename T>
T ConsumeIntegral() {
return provider_.ConsumeIntegral<T>();
}
// Returns a value from |array|, consuming as many bytes as needed to do so.
// |array| must be a fixed-size array.
template <typename T, size_t size>
......
......@@ -43,24 +43,25 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
mz_zip_file file_info = {};
file_info.flag = MZ_ZIP_FLAG_UTF8;
if (data_provider.ConsumeUint8() < 0x08) {
file_info.flag = data_provider.ConsumeUint16();
if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
file_info.flag = data_provider.ConsumeIntegral<uint16_t>();
}
file_info.compression_method = MZ_COMPRESS_METHOD_DEFLATE;
if (data_provider.ConsumeUint8() < 0x08) {
if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
file_info.compression_method = MZ_COMPRESS_METHOD_STORE;
} else if (data_provider.ConsumeUint8() < 0x08) {
file_info.compression_method = data_provider.ConsumeUint16();
} else if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
file_info.compression_method = data_provider.ConsumeIntegral<uint16_t>();
}
if (data_provider.ConsumeUint8() < 0x08) {
file_info.zip64 = data_provider.ConsumeUint16();
if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
file_info.zip64 = data_provider.ConsumeIntegral<uint16_t>();
}
file_info.filename = kTestFileName;
file_info.filename_size = sizeof(kTestFileName);
int16_t compress_level = MZ_COMPRESS_LEVEL_DEFAULT;
if (data_provider.ConsumeUint8() < 0x08) {
compress_level = static_cast<int16_t>(data_provider.ConsumeUint16());
if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
compress_level =
static_cast<int16_t>(data_provider.ConsumeIntegral<uint16_t>());
}
ScopedMzStreamMem out_stream(mz_stream_mem_create(nullptr));
......
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