1 // Copyright 2016 The Chromium Authors
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/socket_bio_adapter.h"
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #include <algorithm>
11
12 #include "base/check_op.h"
13 #include "base/debug/alias.h"
14 #include "base/functional/bind.h"
15 #include "base/location.h"
16 #include "base/notreached.h"
17 #include "base/task/single_thread_task_runner.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_errors.h"
20 #include "net/socket/socket.h"
21 #include "net/socket/stream_socket.h"
22 #include "net/ssl/openssl_ssl_util.h"
23 #include "net/traffic_annotation/network_traffic_annotation.h"
24 #include "third_party/boringssl/src/include/openssl/bio.h"
25
26 namespace {
27
28 const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
29 net::DefineNetworkTrafficAnnotation("socket_bio_adapter", R"(
30 semantics {
31 sender: "Socket BIO Adapter"
32 description:
33 "SocketBIOAdapter is used only internal to //net code as an internal "
34 "detail to implement a TLS connection for a Socket class, and is not "
35 "being called directly outside of this abstraction."
36 trigger:
37 "Establishing a TLS connection to a remote endpoint. There are many "
38 "different ways in which a TLS connection may be triggered, such as "
39 "loading an HTTPS URL."
40 data:
41 "All data sent or received over a TLS connection. This traffic may "
42 "either be the handshake or application data. During the handshake, "
43 "the target host name, user's IP, data related to previous "
44 "handshake, client certificates, and channel ID, may be sent. When "
45 "the connection is used to load an HTTPS URL, the application data "
46 "includes cookies, request headers, and the response body."
47 destination: OTHER
48 destination_other:
49 "Any destination the implementing socket is connected to."
50 }
51 policy {
52 cookies_allowed: NO
53 setting: "This feature cannot be disabled."
54 policy_exception_justification: "Essential for navigation."
55 })");
56
57 } // namespace
58
59 namespace net {
60
SocketBIOAdapter(StreamSocket * socket,int read_buffer_capacity,int write_buffer_capacity,Delegate * delegate)61 SocketBIOAdapter::SocketBIOAdapter(StreamSocket* socket,
62 int read_buffer_capacity,
63 int write_buffer_capacity,
64 Delegate* delegate)
65 : socket_(socket),
66 read_buffer_capacity_(read_buffer_capacity),
67 write_buffer_capacity_(write_buffer_capacity),
68 delegate_(delegate) {
69 bio_.reset(BIO_new(BIOMethod()));
70 BIO_set_data(bio_.get(), this);
71 BIO_set_init(bio_.get(), 1);
72
73 read_callback_ = base::BindRepeating(&SocketBIOAdapter::OnSocketReadComplete,
74 weak_factory_.GetWeakPtr());
75 write_callback_ = base::BindRepeating(
76 &SocketBIOAdapter::OnSocketWriteComplete, weak_factory_.GetWeakPtr());
77 }
78
79 SocketBIOAdapter::~SocketBIOAdapter() {
80 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
81 // BIOs are reference-counted and may outlive the adapter. Clear the pointer
82 // so future operations fail.
83 BIO_set_data(bio_.get(), nullptr);
84 }
85
86 bool SocketBIOAdapter::HasPendingReadData() {
87 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
88 return read_result_ > 0;
89 }
90
91 size_t SocketBIOAdapter::GetAllocationSize() const {
92 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
93 size_t buffer_size = 0;
94 if (read_buffer_)
95 buffer_size += read_buffer_capacity_;
96
97 if (write_buffer_)
98 buffer_size += write_buffer_capacity_;
99 return buffer_size;
100 }
101
102 int SocketBIOAdapter::BIORead(char* out, int len) {
103 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
104 if (len <= 0)
105 return len;
106
107 // If there is no result available synchronously, report any Write() errors
108 // that were observed. Otherwise the application may have encountered a socket
109 // error while writing that would otherwise not be reported until the
110 // application attempted to write again - which it may never do. See
111 // https://crbug.com/249848.
112 if (write_error_ != OK && write_error_ != ERR_IO_PENDING &&
113 (read_result_ == 0 || read_result_ == ERR_IO_PENDING)) {
114 OpenSSLPutNetError(FROM_HERE, write_error_);
115 return -1;
116 }
117
118 if (read_result_ == 0) {
119 // Instantiate the read buffer and read from the socket. Although only |len|
120 // bytes were requested, intentionally read to the full buffer size. The SSL
121 // layer reads the record header and body in separate reads to avoid
122 // overreading, but issuing one is more efficient. SSL sockets are not
123 // reused after shutdown for non-SSL traffic, so overreading is fine.
124 CHECK(!read_buffer_);
125 CHECK_EQ(0, read_offset_);
126 read_buffer_ =
127 base::MakeRefCounted<IOBufferWithSize>(read_buffer_capacity_);
128 read_result_ = ERR_IO_PENDING;
129 int result = socket_->ReadIfReady(
130 read_buffer_.get(), read_buffer_capacity_,
131 base::BindOnce(&SocketBIOAdapter::OnSocketReadIfReadyComplete,
132 weak_factory_.GetWeakPtr()));
133 if (result == ERR_IO_PENDING)
134 read_buffer_ = nullptr;
135 if (result == ERR_READ_IF_READY_NOT_IMPLEMENTED) {
136 result = socket_->Read(read_buffer_.get(), read_buffer_capacity_,
137 read_callback_);
138 }
139 if (result != ERR_IO_PENDING) {
140 // `HandleSocketReadResult` will update `read_result_` based on `result`.
141 HandleSocketReadResult(result);
142 }
143 }
144
145 // There is a pending Read(). Inform the caller to retry when it completes.
146 if (read_result_ == ERR_IO_PENDING) {
147 BIO_set_retry_read(bio());
148 return -1;
149 }
150
151 // If the last Read() failed, report the error.
152 if (read_result_ < 0) {
153 OpenSSLPutNetError(FROM_HERE, read_result_);
154 return -1;
155 }
156
157 // Report the result of the last Read() if non-empty.
158 CHECK_LT(read_offset_, read_result_);
159 len = std::min(len, read_result_ - read_offset_);
160 memcpy(out, read_buffer_->data() + read_offset_, len);
161 read_offset_ += len;
162
163 // Release the buffer when empty.
164 if (read_offset_ == read_result_) {
165 read_buffer_ = nullptr;
166 read_offset_ = 0;
167 read_result_ = 0;
168 }
169
170 return len;
171 }
172
173 void SocketBIOAdapter::HandleSocketReadResult(int result) {
174 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
175 CHECK_NE(ERR_IO_PENDING, result);
176 CHECK_EQ(ERR_IO_PENDING, read_result_);
177
178 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here, so that higher
179 // levels don't report success.
180 if (result == 0)
181 result = ERR_CONNECTION_CLOSED;
182
183 read_result_ = result;
184
185 // The read buffer is no longer needed.
186 if (read_result_ <= 0)
187 read_buffer_ = nullptr;
188 }
189
190 void SocketBIOAdapter::OnSocketReadComplete(int result) {
191 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
192 CHECK_EQ(ERR_IO_PENDING, read_result_);
193
194 HandleSocketReadResult(result);
195 delegate_->OnReadReady();
196 }
197
198 void SocketBIOAdapter::OnSocketReadIfReadyComplete(int result) {
199 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
200 CHECK_EQ(ERR_IO_PENDING, read_result_);
201 CHECK_GE(OK, result);
202
203 // Do not use HandleSocketReadResult() because result == OK doesn't mean EOF.
204 read_result_ = result;
205
206 delegate_->OnReadReady();
207 }
208
209 int SocketBIOAdapter::BIOWrite(const char* in, int len) {
210 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
211 if (len <= 0)
212 return len;
213
214 // If the write buffer is not empty, there must be a pending Write() to flush
215 // it.
216 CHECK(write_buffer_used_ == 0 || write_error_ == ERR_IO_PENDING);
217
218 // If a previous Write() failed, report the error.
219 if (write_error_ != OK && write_error_ != ERR_IO_PENDING) {
220 OpenSSLPutNetError(FROM_HERE, write_error_);
221 return -1;
222 }
223
224 // Instantiate the write buffer if needed.
225 if (!write_buffer_) {
226 CHECK_EQ(0, write_buffer_used_);
227 write_buffer_ = base::MakeRefCounted<GrowableIOBuffer>();
228 write_buffer_->SetCapacity(write_buffer_capacity_);
229 }
230
231 // If the ring buffer is full, inform the caller to try again later.
232 if (write_buffer_used_ == write_buffer_->capacity()) {
233 BIO_set_retry_write(bio());
234 return -1;
235 }
236
237 int bytes_copied = 0;
238
239 // If there is space after the offset, fill it.
240 if (write_buffer_used_ < write_buffer_->RemainingCapacity()) {
241 int chunk =
242 std::min(write_buffer_->RemainingCapacity() - write_buffer_used_, len);
243 memcpy(write_buffer_->data() + write_buffer_used_, in, chunk);
244 in += chunk;
245 len -= chunk;
246 bytes_copied += chunk;
247 write_buffer_used_ += chunk;
248 }
249
250 // If there is still space for remaining data, try to wrap around.
251 if (len > 0 && write_buffer_used_ < write_buffer_->capacity()) {
252 // If there were any room after the offset, the previous branch would have
253 // filled it.
254 CHECK_LE(write_buffer_->RemainingCapacity(), write_buffer_used_);
255 int write_offset = write_buffer_used_ - write_buffer_->RemainingCapacity();
256 int chunk = std::min(len, write_buffer_->capacity() - write_buffer_used_);
257 memcpy(write_buffer_->StartOfBuffer() + write_offset, in, chunk);
258 in += chunk;
259 len -= chunk;
260 bytes_copied += chunk;
261 write_buffer_used_ += chunk;
262 }
263
264 // Either the buffer is now full or there is no more input.
265 CHECK(len == 0 || write_buffer_used_ == write_buffer_->capacity());
266
267 // Schedule a socket Write() if necessary. (The ring buffer may previously
268 // have been empty.)
269 SocketWrite();
270
271 // If a read-interrupting write error was synchronously discovered,
272 // asynchronously notify OnReadReady. See https://crbug.com/249848. Avoid
273 // reentrancy by deferring it to a later event loop iteration.
274 if (write_error_ != OK && write_error_ != ERR_IO_PENDING &&
275 read_result_ == ERR_IO_PENDING) {
276 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
277 FROM_HERE, base::BindOnce(&SocketBIOAdapter::CallOnReadReady,
278 weak_factory_.GetWeakPtr()));
279 }
280
281 return bytes_copied;
282 }
283
284 void SocketBIOAdapter::SocketWrite() {
285 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
286 while (write_error_ == OK && write_buffer_used_ > 0) {
287 int write_buffer_used_old = write_buffer_used_;
288 int write_size =
289 std::min(write_buffer_used_, write_buffer_->RemainingCapacity());
290
291 // TODO(crbug.com/1440692): Remove this once the crash is resolved.
292 char debug[128];
293 snprintf(debug, sizeof(debug),
294 "offset=%d;remaining=%d;used=%d;write_size=%d",
295 write_buffer_->offset(), write_buffer_->RemainingCapacity(),
296 write_buffer_used_, write_size);
297 base::debug::Alias(debug);
298
299 write_error_ = ERR_IO_PENDING;
300 int result = socket_->Write(write_buffer_.get(), write_size,
301 write_callback_, kTrafficAnnotation);
302
303 // TODO(crbug.com/1440692): Remove this once the crash is resolved.
304 char debug2[32];
305 snprintf(debug2, sizeof(debug2), "result=%d", result);
306 base::debug::Alias(debug2);
307
308 // If `write_buffer_used_` changed across a call to the underlying socket,
309 // something went very wrong.
310 //
311 // TODO(crbug.com/1440692): Remove this once the crash is resolved.
312 CHECK_EQ(write_buffer_used_old, write_buffer_used_);
313 if (result != ERR_IO_PENDING) {
314 // `HandleSocketWriteResult` will update `write_error_` based on `result.
315 HandleSocketWriteResult(result);
316 }
317 }
318 }
319
HandleSocketWriteResult(int result)320 void SocketBIOAdapter::HandleSocketWriteResult(int result) {
321 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
322 CHECK_NE(ERR_IO_PENDING, result);
323 CHECK_EQ(ERR_IO_PENDING, write_error_);
324
325 if (result < 0) {
326 write_error_ = result;
327
328 // The write buffer is no longer needed.
329 write_buffer_ = nullptr;
330 write_buffer_used_ = 0;
331 return;
332 }
333
334 // Advance the ring buffer.
335 CHECK_LE(result, write_buffer_used_);
336 CHECK_LE(result, write_buffer_->RemainingCapacity());
337 write_buffer_->set_offset(write_buffer_->offset() + result);
338 write_buffer_used_ -= result;
339 if (write_buffer_->RemainingCapacity() == 0)
340 write_buffer_->set_offset(0);
341 write_error_ = OK;
342
343 // Release the write buffer if empty.
344 if (write_buffer_used_ == 0)
345 write_buffer_ = nullptr;
346 }
347
348 void SocketBIOAdapter::OnSocketWriteComplete(int result) {
349 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
350 CHECK_EQ(ERR_IO_PENDING, write_error_);
351
352 bool was_full = write_buffer_used_ == write_buffer_->capacity();
353
354 HandleSocketWriteResult(result);
355 SocketWrite();
356
357 // If transitioning from being unable to accept data to being able to, signal
358 // OnWriteReady.
359 if (was_full) {
360 base::WeakPtr<SocketBIOAdapter> guard(weak_factory_.GetWeakPtr());
361 delegate_->OnWriteReady();
362 // OnWriteReady may delete the adapter.
363 if (!guard)
364 return;
365 }
366
367 // Write errors are fed back into BIO_read once the read buffer is empty. If
368 // BIO_read is currently blocked, signal early that a read result is ready.
369 if (result < 0 && read_result_ == ERR_IO_PENDING)
370 delegate_->OnReadReady();
371 }
372
373 void SocketBIOAdapter::CallOnReadReady() {
374 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
375 if (read_result_ == ERR_IO_PENDING)
376 delegate_->OnReadReady();
377 }
378
379 SocketBIOAdapter* SocketBIOAdapter::GetAdapter(BIO* bio) {
380 SocketBIOAdapter* adapter =
381 reinterpret_cast<SocketBIOAdapter*>(BIO_get_data(bio));
382 if (adapter) {
383 CHECK_EQ(bio, adapter->bio());
384 }
385 return adapter;
386 }
387
388 int SocketBIOAdapter::BIOWriteWrapper(BIO* bio, const char* in, int len) {
389 BIO_clear_retry_flags(bio);
390
391 SocketBIOAdapter* adapter = GetAdapter(bio);
392 if (!adapter) {
393 OpenSSLPutNetError(FROM_HERE, ERR_UNEXPECTED);
394 return -1;
395 }
396
397 return adapter->BIOWrite(in, len);
398 }
399
400 int SocketBIOAdapter::BIOReadWrapper(BIO* bio, char* out, int len) {
401 BIO_clear_retry_flags(bio);
402
403 SocketBIOAdapter* adapter = GetAdapter(bio);
404 if (!adapter) {
405 OpenSSLPutNetError(FROM_HERE, ERR_UNEXPECTED);
406 return -1;
407 }
408
409 return adapter->BIORead(out, len);
410 }
411
412 long SocketBIOAdapter::BIOCtrlWrapper(BIO* bio,
413 int cmd,
414 long larg,
415 void* parg) {
416 switch (cmd) {
417 case BIO_CTRL_FLUSH:
418 // The SSL stack requires BIOs handle BIO_flush.
419 return 1;
420 }
421
422 NOTIMPLEMENTED();
423 return 0;
424 }
425
426 const BIO_METHOD* SocketBIOAdapter::BIOMethod() {
427 static const BIO_METHOD* kMethod = []() {
428 BIO_METHOD* method = BIO_meth_new(0, nullptr);
429 CHECK(method);
430 CHECK(BIO_meth_set_write(method, SocketBIOAdapter::BIOWriteWrapper));
431 CHECK(BIO_meth_set_read(method, SocketBIOAdapter::BIOReadWrapper));
432 CHECK(BIO_meth_set_ctrl(method, SocketBIOAdapter::BIOCtrlWrapper));
433 return method;
434 }();
435 return kMethod;
436 }
437
438 } // namespace net
439