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

Side by Side Diff: net/socket/fuzzed_socket.cc

Issue 1854813004: Add SOCKS4 and SOCKS5 fuzzers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Response to comments 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 unified diff | Download patch
« no previous file with comments | « net/socket/fuzzed_socket.h ('k') | net/socket/socks5_client_socket_fuzzer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/socket/fuzzed_socket.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "net/base/io_buffer.h"
12
13 namespace net {
14
15 namespace {
16
17 // Subset of the socket errors that can be returned by normal socket reads /
18 // writes. The first one is returned when no more input data remains, so it's
19 // one of the most common ones.
20 const Error kReadWriteErrors[] = {ERR_CONNECTION_CLOSED, ERR_FAILED,
21 ERR_TIMED_OUT, ERR_CONNECTION_RESET};
22
23 } // namespace
24
25 FuzzedSocket::FuzzedSocket(const uint8_t* data,
26 size_t data_size,
27 const BoundNetLog& bound_net_log)
28 : data_(reinterpret_cast<const char*>(data), data_size),
29 bound_net_log_(bound_net_log),
30 weak_factory_(this) {}
31
32 FuzzedSocket::~FuzzedSocket() {}
33
34 int FuzzedSocket::Read(IOBuffer* buf,
35 int buf_len,
36 const CompletionCallback& callback) {
37 DCHECK(!read_pending_);
38
39 bool sync;
40 int result;
41
42 if (net_error_ != OK) {
43 // If an error has already been generated, use it to determine what to do.
44 result = net_error_;
45 sync = !error_pending_;
46 } else {
47 // Otherwise, use |data_|.
48 uint8_t random_val = ConsumeUint8FromData();
49 sync = !!(random_val & 0x01);
50 result = random_val >> 1;
51 if (result > buf_len)
52 result = buf_len;
53 // Can't read more data than is available in |data_|.
54 if (static_cast<size_t>(result) > data_.length())
55 result = data_.length();
56
57 if (result == 0) {
58 net_error_ = ConsumeReadWriteErrorFromData();
59 result = net_error_;
60 if (!sync)
61 error_pending_ = true;
62 } else {
63 memcpy(buf->data(), data_.data(), result);
64 data_ = data_.substr(result);
65 }
66 }
67
68 // Graceful close of a socket returns OK, at least in theory. This doesn't
69 // perfectly reflect real socket behavior, but close enough.
70 if (result == ERR_CONNECTION_CLOSED)
71 result = 0;
72
73 if (sync) {
74 if (result > 0)
75 total_bytes_read_ += result;
76 return result;
77 }
78
79 read_pending_ = true;
80 base::ThreadTaskRunnerHandle::Get()->PostTask(
81 FROM_HERE, base::Bind(&FuzzedSocket::OnReadComplete,
82 weak_factory_.GetWeakPtr(), callback, result));
83 return ERR_IO_PENDING;
84 }
85
86 int FuzzedSocket::Write(IOBuffer* buf,
87 int buf_len,
88 const CompletionCallback& callback) {
89 DCHECK(!write_pending_);
90
91 bool sync;
92 int result;
93
94 if (net_error_ != OK) {
95 // If an error has already been generated, use it to determine what to do.
96 result = net_error_;
97 sync = !error_pending_;
98 } else {
99 // Otherwise, use |data_|.
100 uint8_t random_val = ConsumeUint8FromData();
101 sync = !!(random_val & 0x01);
102 result = random_val >> 1;
103 if (result > buf_len)
104 result = buf_len;
105 if (result == 0) {
106 net_error_ = ConsumeReadWriteErrorFromData();
107 result = net_error_;
108 if (!sync)
109 error_pending_ = true;
110 }
111 }
112
113 if (sync) {
114 if (result > 0)
115 total_bytes_written_ += result;
116 return result;
117 }
118
119 write_pending_ = true;
120 base::ThreadTaskRunnerHandle::Get()->PostTask(
121 FROM_HERE, base::Bind(&FuzzedSocket::OnWriteComplete,
122 weak_factory_.GetWeakPtr(), callback, result));
123 return ERR_IO_PENDING;
124 }
125
126 int FuzzedSocket::SetReceiveBufferSize(int32_t size) {
127 return OK;
128 }
129
130 int FuzzedSocket::SetSendBufferSize(int32_t size) {
131 return OK;
132 }
133
134 int FuzzedSocket::Connect(const CompletionCallback& callback) {
135 // Sockets can normally be reused, but don't support it here.
136 DCHECK_NE(net_error_, OK);
137 DCHECK(!read_pending_);
138 DCHECK(!write_pending_);
139 DCHECK(!error_pending_);
140 DCHECK(!total_bytes_read_);
141 DCHECK(!total_bytes_written_);
142
143 net_error_ = OK;
144 return OK;
145 }
146
147 void FuzzedSocket::Disconnect() {
148 net_error_ = ERR_CONNECTION_CLOSED;
149 weak_factory_.InvalidateWeakPtrs();
150 read_pending_ = false;
151 write_pending_ = false;
152 error_pending_ = false;
153 }
154
155 bool FuzzedSocket::IsConnected() const {
156 return net_error_ != OK && !error_pending_;
157 }
158
159 bool FuzzedSocket::IsConnectedAndIdle() const {
160 return IsConnected();
161 }
162
163 int FuzzedSocket::GetPeerAddress(IPEndPoint* address) const {
164 if (!IsConnected())
165 return ERR_SOCKET_NOT_CONNECTED;
166 *address = IPEndPoint(IPAddress(127, 0, 0, 1), 80);
167 return OK;
168 }
169
170 int FuzzedSocket::GetLocalAddress(IPEndPoint* address) const {
171 if (!IsConnected())
172 return ERR_SOCKET_NOT_CONNECTED;
173 *address = IPEndPoint(IPAddress(127, 0, 0, 1), 43434);
174 return OK;
175 }
176
177 const BoundNetLog& FuzzedSocket::NetLog() const {
178 return bound_net_log_;
179 }
180
181 void FuzzedSocket::SetSubresourceSpeculation() {}
182
183 void FuzzedSocket::SetOmniboxSpeculation() {}
184
185 bool FuzzedSocket::WasEverUsed() const {
186 return total_bytes_written_ != 0 || total_bytes_read_ != 0;
187 }
188
189 void FuzzedSocket::EnableTCPFastOpenIfSupported() {}
190
191 bool FuzzedSocket::WasNpnNegotiated() const {
192 return false;
193 }
194
195 NextProto FuzzedSocket::GetNegotiatedProtocol() const {
196 return kProtoUnknown;
197 }
198
199 bool FuzzedSocket::GetSSLInfo(SSLInfo* ssl_info) {
200 return false;
201 }
202
203 void FuzzedSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
204 out->clear();
205 }
206
207 void FuzzedSocket::ClearConnectionAttempts() {}
208
209 void FuzzedSocket::AddConnectionAttempts(const ConnectionAttempts& attempts) {}
210
211 int64_t FuzzedSocket::GetTotalReceivedBytes() const {
212 return total_bytes_read_;
213 }
214
215 uint8_t FuzzedSocket::ConsumeUint8FromData() {
216 size_t length = data_.length();
217 if (!length)
218 return 0;
219 uint8_t out = data_[length - 1];
220 data_ = data_.substr(0, length - 1);
221 return out;
222 }
223
224 Error FuzzedSocket::ConsumeReadWriteErrorFromData() {
225 return kReadWriteErrors[ConsumeUint8FromData() % arraysize(kReadWriteErrors)];
226 }
227
228 void FuzzedSocket::OnReadComplete(const CompletionCallback& callback,
229 int result) {
230 CHECK(read_pending_);
231 read_pending_ = false;
232 if (result <= 0) {
233 error_pending_ = false;
234 } else {
235 total_bytes_read_ += result;
236 }
237 callback.Run(result);
238 }
239
240 void FuzzedSocket::OnWriteComplete(const CompletionCallback& callback,
241 int result) {
242 CHECK(write_pending_);
243 write_pending_ = false;
244 if (result <= 0) {
245 error_pending_ = false;
246 } else {
247 total_bytes_written_ += result;
248 }
249 callback.Run(result);
250 }
251
252 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/fuzzed_socket.h ('k') | net/socket/socks5_client_socket_fuzzer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698