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

Unified Diff: net/socket/ssl_client_socket_openssl.cc

Issue 148213019: Close the correct end of the BIO pair on transport send failures in openssl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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/ssl_client_socket_openssl.cc
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 3925ca1a36ec6b401d4625bb7d0055c308ab0943..8735dc725a68ffcc9cdac240dac97aeca8f5f26c 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -343,6 +343,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
transport_recv_eof_(false),
weak_factory_(this),
pending_read_error_(kNoPendingReadResult),
+ transport_write_error_(OK),
completed_handshake_(false),
client_auth_cert_needed_(false),
cert_verifier_(context.cert_verifier),
@@ -1204,7 +1205,7 @@ int SSLClientSocketOpenSSL::BufferRecv(void) {
if (rv == ERR_IO_PENDING) {
transport_recv_busy_ = true;
} else {
- TransportReadComplete(rv);
+ rv = TransportReadComplete(rv);
}
return rv;
}
@@ -1216,7 +1217,7 @@ void SSLClientSocketOpenSSL::BufferSendComplete(int result) {
}
void SSLClientSocketOpenSSL::BufferRecvComplete(int result) {
- TransportReadComplete(result);
+ result = TransportReadComplete(result);
OnRecvComplete(result);
}
@@ -1224,9 +1225,19 @@ void SSLClientSocketOpenSSL::TransportWriteComplete(int result) {
DCHECK(ERR_IO_PENDING != result);
if (result < 0) {
// Got a socket write error; close the BIO to indicate this upward.
+ //
+ // TODO(davidben): The value of |result| gets lost. Feed the error back into
+ // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with
+ // BIO_set_callback.
DVLOG(1) << "TransportWriteComplete error " << result;
+ (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
davidben 2014/02/04 19:27:57 Could get away with even avoiding this line for mi
davidben 2014/02/04 19:27:57 It looks like sometimes OpenSSL wraps the wbio in
Ryan Sleevi 2014/02/04 20:45:02 Future work: Should we be using BIO_set_close() in
davidben 2014/02/04 23:00:11 Hrm. That seems to set the shutdown flag on the BI
+
+ // Match the fix for http://crbug.com/249848 in NSS by erroring future reads
+ // from the socket after a write error.
+ //
+ // TODO(davidben): Avoid having read and write ends interact this way.
+ transport_write_error_ = result;
(void)BIO_shutdown_wr(transport_bio_);
- BIO_set_mem_eof_return(transport_bio_, 0);
davidben 2014/02/04 19:27:57 Looks like these calls don't do anything in BIO pa
send_buffer_ = NULL;
davidben 2014/02/04 19:27:57 This line is sort of funny. The next time we get a
Ryan Sleevi 2014/02/04 20:45:02 I'm not sure I follow why it's funny. We just had
davidben 2014/02/04 23:00:11 Keeping send_buffer_ around avoids the succeeds wi
} else {
DCHECK(send_buffer_.get());
@@ -1237,7 +1248,7 @@ void SSLClientSocketOpenSSL::TransportWriteComplete(int result) {
}
}
-void SSLClientSocketOpenSSL::TransportReadComplete(int result) {
+int SSLClientSocketOpenSSL::TransportReadComplete(int result) {
DCHECK(ERR_IO_PENDING != result);
if (result <= 0) {
DVLOG(1) << "TransportReadComplete result " << result;
@@ -1246,8 +1257,11 @@ void SSLClientSocketOpenSSL::TransportReadComplete(int result) {
// relay up to the SSL socket client (i.e. via DoReadCallback).
if (result == 0)
transport_recv_eof_ = true;
- BIO_set_mem_eof_return(transport_bio_, 0);
(void)BIO_shutdown_wr(transport_bio_);
+ } else if (transport_write_error_ < 0) {
+ // Mirror transport write errors as read failures; transport_bio_ has been
+ // shut down by TransportWriteComplete, so the BIO_write will fail.
+ result = transport_write_error_;
Ryan Sleevi 2014/02/04 20:45:02 Let's add bug numbers. This is perhaps the most co
davidben 2014/02/04 23:00:11 Agreed. I kept it this way just to minimize behavi
} else {
DCHECK(recv_buffer_.get());
int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
@@ -1259,6 +1273,7 @@ void SSLClientSocketOpenSSL::TransportReadComplete(int result) {
}
recv_buffer_ = NULL;
transport_recv_busy_ = false;
+ return result;
}
int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,

Powered by Google App Engine
This is Rietveld 408576698