Skip to content

Commit 5cbb984

Browse files
Revert other changes, guard ERR_SYSCALL return
1 parent 943f8c9 commit 5cbb984

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

ssl/ssl_lib.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *read_bytes) {
10451045
}
10461046
int ret = SSL_read(ssl, buf, (int)num);
10471047
if (ret <= 0) {
1048-
return ret;
1048+
return 0;
10491049
}
10501050
if (read_bytes != nullptr) {
10511051
*read_bytes = ret;
@@ -1144,7 +1144,7 @@ int SSL_write_ex(SSL *ssl, const void *buf, size_t num, size_t *written) {
11441144
}
11451145
int ret = SSL_write(ssl, buf, (int)num);
11461146
if (ret <= 0) {
1147-
return ret;
1147+
return 0;
11481148
}
11491149
if (written != nullptr) {
11501150
*written = ret;
@@ -1388,8 +1388,11 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
13881388
}
13891389
// An EOF was observed which violates the protocol, and the underlying
13901390
// transport does not participate in the error queue. Bubble up to the
1391-
// caller.
1392-
return SSL_ERROR_SYSCALL;
1391+
// caller. Do not consider retryable |rwstate| EOF.
1392+
if (ssl->s3->rwstate != SSL_ERROR_WANT_READ
1393+
&& ssl->s3->rwstate != SSL_ERROR_WANT_WRITE) {
1394+
return SSL_ERROR_SYSCALL;
1395+
}
13931396
}
13941397

13951398
switch (ssl->s3->rwstate) {

ssl/ssl_test.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10458,6 +10458,57 @@ TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
1045810458
write_failed = false;
1045910459
}
1046010460

10461+
// Test that intermittent inability to read results in retryable error
10462+
TEST(SSLTest, IntermittentEmptyRead) {
10463+
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
10464+
bssl::UniquePtr<SSL_CTX> server_ctx =
10465+
CreateContextWithTestCertificate(TLS_method());
10466+
ASSERT_TRUE(client_ctx);
10467+
ASSERT_TRUE(server_ctx);
10468+
bssl::UniquePtr<SSL> client, server;
10469+
ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
10470+
server_ctx.get()));
10471+
10472+
// Create a fake read BIO that returns 0 on read to simulate empty read
10473+
bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
10474+
ASSERT_TRUE(method);
10475+
BIO_meth_set_create(method.get(), [](BIO *b) -> int {
10476+
BIO_set_init(b, 1);
10477+
return 1;
10478+
});
10479+
BIO_meth_set_read(method.get(), [](BIO *, char *, int) -> int {
10480+
return 0;
10481+
});
10482+
bssl::UniquePtr<BIO> rbio_empty(BIO_new(method.get()));
10483+
ASSERT_TRUE(rbio_empty);
10484+
BIO_set_flags(rbio_empty.get(), BIO_FLAGS_READ);
10485+
10486+
// Save off client rbio and use empty read BIO
10487+
bssl::UniquePtr<BIO> client_rbio(SSL_get_rbio(client.get()));
10488+
ASSERT_TRUE(client_rbio);
10489+
// Up-ref |client_rbio| as SSL_CTX dtor will also attempt to free it
10490+
ASSERT_TRUE(BIO_up_ref(client_rbio.get()));
10491+
SSL_set0_rbio(client.get(), rbio_empty.release());
10492+
10493+
// Server writes some data to the client
10494+
const uint8_t data[1] = {0};
10495+
int ret = SSL_write(server.get(), data, (int) sizeof(data));
10496+
EXPECT_EQ(ret, (int) sizeof(data));
10497+
EXPECT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_NONE);
10498+
10499+
// On empty read, client should still want a read so caller will retry
10500+
uint8_t buf[1];
10501+
ret = SSL_read(client.get(), buf, sizeof(buf));
10502+
EXPECT_EQ(ret, 0);
10503+
EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_WANT_READ);
10504+
10505+
// Reset client rbio, read should succeed
10506+
SSL_set0_rbio(client.get(), client_rbio.release());
10507+
ret = SSL_read(client.get(), buf, sizeof(buf));
10508+
EXPECT_EQ(ret, (int) sizeof(buf));
10509+
EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_NONE);
10510+
}
10511+
1046110512
// Test that |SSL_shutdown|, when quiet shutdown is enabled, simulates receiving
1046210513
// a close_notify, down to |SSL_read| reporting |SSL_ERROR_ZERO_RETURN|.
1046310514
TEST(SSLTest, QuietShutdown) {

0 commit comments

Comments
 (0)