summaryrefslogtreecommitdiffstats
path: root/net/socket/ssl_client_socket_nss.cc
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-16 19:36:31 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-16 19:36:31 +0000
commitc0e4dd1e6b56543fb186289e5a45463d0b81d1e8 (patch)
tree250241fdca7730e2e18af407e3edcdb9882f4375 /net/socket/ssl_client_socket_nss.cc
parentc1e3cefb7603bb0bac40cd8e73956e662504ee72 (diff)
downloadchromium_src-c0e4dd1e6b56543fb186289e5a45463d0b81d1e8.zip
chromium_src-c0e4dd1e6b56543fb186289e5a45463d0b81d1e8.tar.gz
chromium_src-c0e4dd1e6b56543fb186289e5a45463d0b81d1e8.tar.bz2
Prevent the infinite loop inside SSLClientSocketNSS::OnSendComplete.
Two fixes are added. 1) We stay in the loop only if we will call DoPayloadRead or DoPayloadWrite in the next iteration. 2) Don't call BufferRecv again if BufferRecv has reported EOF before. Each fix alone prevents the infinite loop. The second fix is less risky. If necessary, we can go with just the second fix. R=rsleevi@chromium.org BUG=127822 TEST=SSLServerSocketTest.WriteAfterPeerClose in net_unittests Review URL: https://chromiumcodereview.appspot.com/10382186 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137485 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/ssl_client_socket_nss.cc')
-rw-r--r--net/socket/ssl_client_socket_nss.cc16
1 files changed, 12 insertions, 4 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index b84805e..aba4f7a 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -430,6 +430,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
const SSLClientSocketContext& context)
: transport_send_busy_(false),
transport_recv_busy_(false),
+ transport_recv_eof_(false),
transport_(transport_socket),
host_and_port_(host_and_port),
ssl_config_(ssl_config),
@@ -633,6 +634,7 @@ void SSLClientSocketNSS::Disconnect() {
user_write_callback_.Reset();
transport_send_busy_ = false;
transport_recv_busy_ = false;
+ transport_recv_eof_ = false;
user_read_buf_ = NULL;
user_read_buf_len_ = 0;
user_write_buf_ = NULL;
@@ -1219,6 +1221,7 @@ void SSLClientSocketNSS::OnSendComplete(int result) {
network_moved = DoTransportIO();
} while (rv_read == ERR_IO_PENDING &&
rv_write == ERR_IO_PENDING &&
+ (user_read_buf_ || user_write_buf_) &&
network_moved);
if (user_read_buf_ && rv_read != ERR_IO_PENDING)
@@ -1922,7 +1925,7 @@ bool SSLClientSocketNSS::DoTransportIO() {
if (rv > 0)
network_moved = true;
} while (rv > 0);
- if (BufferRecv() >= 0)
+ if (!transport_recv_eof_ && BufferRecv() >= 0)
network_moved = true;
}
LeaveFunction(network_moved);
@@ -1932,7 +1935,7 @@ bool SSLClientSocketNSS::DoTransportIO() {
// Return 0 for EOF,
// > 0 for bytes transferred immediately,
// < 0 for error (or the non-error ERR_IO_PENDING).
-int SSLClientSocketNSS::BufferSend(void) {
+int SSLClientSocketNSS::BufferSend() {
if (transport_send_busy_)
return ERR_IO_PENDING;
@@ -1971,7 +1974,7 @@ void SSLClientSocketNSS::BufferSendComplete(int result) {
LeaveFunction("");
}
-int SSLClientSocketNSS::BufferRecv(void) {
+int SSLClientSocketNSS::BufferRecv() {
if (transport_recv_busy_) return ERR_IO_PENDING;
char* buf;
@@ -1990,8 +1993,11 @@ int SSLClientSocketNSS::BufferRecv(void) {
if (rv == ERR_IO_PENDING) {
transport_recv_busy_ = true;
} else {
- if (rv > 0)
+ if (rv > 0) {
memcpy(buf, recv_buffer_->data(), rv);
+ } else if (rv == 0) {
+ transport_recv_eof_ = true;
+ }
memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
recv_buffer_ = NULL;
}
@@ -2006,6 +2012,8 @@ void SSLClientSocketNSS::BufferRecvComplete(int result) {
char* buf;
memio_GetReadParams(nss_bufs_, &buf);
memcpy(buf, recv_buffer_->data(), result);
+ } else if (result == 0) {
+ transport_recv_eof_ = true;
}
recv_buffer_ = NULL;
memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));