Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Unified Diff: net/socket/fuzzed_socket.cc

Issue 1917503002: URLRequest fuzzer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fuzz
Patch Set: Remove tab Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/socket/fuzzed_socket.cc
diff --git a/net/socket/fuzzed_socket.cc b/net/socket/fuzzed_socket.cc
index c00faafd3f655729cbdbdcd10fabceed1cdd8317..df2ba649413c8686b3bacffc25cdba86425379e5 100644
--- a/net/socket/fuzzed_socket.cc
+++ b/net/socket/fuzzed_socket.cc
@@ -8,13 +8,21 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/thread_task_runner_handle.h"
+#include "net/base/fuzzed_data_provider.h"
#include "net/base/io_buffer.h"
namespace net {
namespace {
-// Subset of the socket errors that can be returned by normal socket reads /
+// Some of the socket errors that can be returned by normal socket connection
+// attempts.
+const Error kConnectErrors[] = {
+ ERR_CONNECTION_RESET, ERR_CONNECTION_CLOSED, ERR_FAILED,
+ ERR_CONNECTION_TIMED_OUT, ERR_ACCESS_DENIED, ERR_CONNECTION_REFUSED,
+ ERR_ADDRESS_UNREACHABLE};
+
+// Some of the socket errors that can be returned by normal socket reads /
// writes. The first one is returned when no more input data remains, so it's
// one of the most common ones.
const Error kReadWriteErrors[] = {ERR_CONNECTION_CLOSED, ERR_FAILED,
@@ -22,11 +30,11 @@ const Error kReadWriteErrors[] = {ERR_CONNECTION_CLOSED, ERR_FAILED,
} // namespace
-FuzzedSocket::FuzzedSocket(const uint8_t* data,
- size_t data_size,
- const BoundNetLog& bound_net_log)
- : data_(reinterpret_cast<const char*>(data), data_size),
- bound_net_log_(bound_net_log),
+FuzzedSocket::FuzzedSocket(FuzzedDataProvider* data_provider,
+ net::NetLog* net_log)
+ : data_provider_(data_provider),
+ bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
+ remote_address_(IPEndPoint(IPAddress(127, 0, 0, 1), 80)),
weak_factory_(this) {}
FuzzedSocket::~FuzzedSocket() {}
@@ -34,6 +42,7 @@ FuzzedSocket::~FuzzedSocket() {}
int FuzzedSocket::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
+ DCHECK(!connect_pending_);
DCHECK(!read_pending_);
bool sync;
@@ -44,24 +53,20 @@ int FuzzedSocket::Read(IOBuffer* buf,
result = net_error_;
sync = !error_pending_;
} else {
- // Otherwise, use |data_|.
- uint8_t random_val = ConsumeUint8FromData();
- sync = !!(random_val & 0x01);
- result = random_val >> 1;
+ // Otherwise, use |data_provider_|.
+ sync = !!data_provider_->ConsumeBits(1);
+ result = data_provider_->ConsumeBits(7);
if (result > buf_len)
result = buf_len;
- // Can't read more data than is available in |data_|.
- if (static_cast<size_t>(result) > data_.length())
- result = data_.length();
+
+ if (result > 0)
+ result = data_provider_->ConsumeBytes(buf->data(), result);
if (result == 0) {
net_error_ = ConsumeReadWriteErrorFromData();
result = net_error_;
if (!sync)
error_pending_ = true;
- } else {
- memcpy(buf->data(), data_.data(), result);
- data_ = data_.substr(result);
}
}
@@ -86,6 +91,7 @@ int FuzzedSocket::Read(IOBuffer* buf,
int FuzzedSocket::Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
+ DCHECK(!connect_pending_);
DCHECK(!write_pending_);
bool sync;
@@ -97,9 +103,8 @@ int FuzzedSocket::Write(IOBuffer* buf,
sync = !error_pending_;
} else {
// Otherwise, use |data_|.
- uint8_t random_val = ConsumeUint8FromData();
- sync = !!(random_val & 0x01);
- result = random_val >> 1;
+ sync = !!data_provider_->ConsumeBits(1);
+ result = data_provider_->ConsumeBits(7);
if (result > buf_len)
result = buf_len;
if (result == 0) {
@@ -134,19 +139,46 @@ int FuzzedSocket::SetSendBufferSize(int32_t size) {
int FuzzedSocket::Connect(const CompletionCallback& callback) {
// Sockets can normally be reused, but don't support it here.
DCHECK_NE(net_error_, OK);
+ DCHECK(!connect_pending_);
DCHECK(!read_pending_);
DCHECK(!write_pending_);
DCHECK(!error_pending_);
DCHECK(!total_bytes_read_);
DCHECK(!total_bytes_written_);
- net_error_ = OK;
- return OK;
+ int sync = true;
+ Error result = OK;
+ if (fuzz_connect_result_) {
+ // Decide if sync or async. Use async, if no data is left.
+ sync = !!data_provider_->ConsumeBits(1);
+ // Decide if the connect succeeds or not. Fail, if no data is left.
+ bool is_error = !data_provider_->ConsumeBits(1);
+
+ // Remove 6 bits, so a full byte as been consumed. If the connect is going
+ // to fail, use them to decide the error code. Otherwise, throw them away.
+ uint32_t error_bits = data_provider_->ConsumeBits(6);
+ if (is_error)
+ result = kConnectErrors[error_bits % arraysize(kConnectErrors)];
+ }
+
+ if (sync) {
+ net_error_ = result;
+ return result;
+ }
+
+ connect_pending_ = true;
+ if (result != OK)
+ error_pending_ = true;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&FuzzedSocket::OnConnectComplete,
+ weak_factory_.GetWeakPtr(), callback, result));
+ return ERR_IO_PENDING;
}
void FuzzedSocket::Disconnect() {
net_error_ = ERR_CONNECTION_CLOSED;
weak_factory_.InvalidateWeakPtrs();
+ connect_pending_ = false;
read_pending_ = false;
write_pending_ = false;
error_pending_ = false;
@@ -212,17 +244,9 @@ int64_t FuzzedSocket::GetTotalReceivedBytes() const {
return total_bytes_read_;
}
-uint8_t FuzzedSocket::ConsumeUint8FromData() {
- size_t length = data_.length();
- if (!length)
- return 0;
- uint8_t out = data_[length - 1];
- data_ = data_.substr(0, length - 1);
- return out;
-}
-
Error FuzzedSocket::ConsumeReadWriteErrorFromData() {
- return kReadWriteErrors[ConsumeUint8FromData() % arraysize(kReadWriteErrors)];
+ return kReadWriteErrors[data_provider_->ConsumeBits(8) %
+ arraysize(kReadWriteErrors)];
}
void FuzzedSocket::OnReadComplete(const CompletionCallback& callback,
@@ -249,4 +273,13 @@ void FuzzedSocket::OnWriteComplete(const CompletionCallback& callback,
callback.Run(result);
}
+void FuzzedSocket::OnConnectComplete(const CompletionCallback& callback,
+ int result) {
+ CHECK(connect_pending_);
+ connect_pending_ = false;
+ if (result < 0)
+ error_pending_ = false;
+ callback.Run(result);
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698