Fix bssl handling of buffered read data.

If the peer sends us one record that exceeds buffer, the socket will no
longer flag as readable, because data has been consumed, but SSL_read
should still be called to drain data. bssl would instead not notice and
only surface the data later on.

This can (currently) be reproduced by sending "HEAD / HTTP/1.1" to
www.google.com.

Change-Id: I73cdbe104ba6be56fc033429999e630f0eb852d8
Reviewed-on: https://boringssl-review.googlesource.com/28166
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2018-05-06 02:45:47 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent 28385db6e1
commit 3d9705d0a4

View File

@ -699,28 +699,30 @@ bool TransferData(SSL *ssl, int sock) {
}
if (socket_ready) {
uint8_t buffer[512];
int ssl_ret = SSL_read(ssl, buffer, sizeof(buffer));
for (;;) {
uint8_t buffer[512];
int ssl_ret = SSL_read(ssl, buffer, sizeof(buffer));
if (ssl_ret < 0) {
int ssl_err = SSL_get_error(ssl, ssl_ret);
if (ssl_err == SSL_ERROR_WANT_READ) {
continue;
if (ssl_ret < 0) {
int ssl_err = SSL_get_error(ssl, ssl_ret);
if (ssl_err == SSL_ERROR_WANT_READ) {
break;
}
PrintSSLError(stderr, "Error while reading", ssl_err, ssl_ret);
return false;
} else if (ssl_ret == 0) {
return true;
}
PrintSSLError(stderr, "Error while reading", ssl_err, ssl_ret);
return false;
} else if (ssl_ret == 0) {
return true;
}
ssize_t n;
do {
n = BORINGSSL_WRITE(1, buffer, ssl_ret);
} while (n == -1 && errno == EINTR);
ssize_t n;
do {
n = BORINGSSL_WRITE(1, buffer, ssl_ret);
} while (n == -1 && errno == EINTR);
if (n != ssl_ret) {
fprintf(stderr, "Short write to stderr.\n");
return false;
if (n != ssl_ret) {
fprintf(stderr, "Short write to stderr.\n");
return false;
}
}
}
}