mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Merge branch '2611-doth-failure' into 'main'
Fix "doth" system test failure with SSL_ERROR_SYSCALL (5) See merge request isc-projects/bind9!4863
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include <uv.h>
|
||||
@@ -327,8 +328,8 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
int pending, tls_status = SSL_ERROR_NONE;
|
||||
int rv = 0;
|
||||
bool sent_shutdown = false, received_shutdown = false;
|
||||
size_t len = 0;
|
||||
int saved_errno = 0;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
@@ -359,6 +360,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
||||
received_data->length, &len);
|
||||
if (rv <= 0 || len != received_data->length) {
|
||||
result = ISC_R_TLSERROR;
|
||||
saved_errno = errno;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -372,7 +374,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
||||
} else if (send_data != NULL) {
|
||||
INSIST(received_data == NULL);
|
||||
INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
|
||||
received_shutdown =
|
||||
bool received_shutdown =
|
||||
((SSL_get_shutdown(sock->tlsstream.tls) &
|
||||
SSL_RECEIVED_SHUTDOWN) != 0);
|
||||
rv = SSL_write_ex(sock->tlsstream.tls,
|
||||
@@ -410,6 +412,28 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
||||
}
|
||||
}
|
||||
tls_status = SSL_get_error(sock->tlsstream.tls, rv);
|
||||
saved_errno = errno;
|
||||
|
||||
/* See "BUGS" section at:
|
||||
* https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
|
||||
*
|
||||
* It is mentioned there that when TLS status equals
|
||||
* SSL_ERROR_SYSCALL AND errno == 0 it means that underlying
|
||||
* transport layer returned EOF prematurely. However, we are
|
||||
* managing the transport ourselves, so we should just resume
|
||||
* reading from the TCP socket.
|
||||
*
|
||||
* It seems that this case has been handled properly on modern
|
||||
* versions of OpenSSL. That being said, the situation goes in
|
||||
* line with the manual: it is briefly mentioned there that
|
||||
* SSL_ERROR_SYSCALL might be returned not only in a case of
|
||||
* low-level errors (like system call failures).
|
||||
*/
|
||||
if (tls_status == SSL_ERROR_SYSCALL && saved_errno == 0 &&
|
||||
received_data == NULL && send_data == NULL && finish == false)
|
||||
{
|
||||
tls_status = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
|
||||
pending = tls_process_outgoing(sock, finish, send_data);
|
||||
if (pending > 0) {
|
||||
@@ -420,11 +444,6 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
||||
switch (tls_status) {
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
if (sent_shutdown && received_shutdown) {
|
||||
/* clean shutdown */
|
||||
isc_nm_cancelread(sock->outerhandle);
|
||||
isc__nm_tls_close(sock);
|
||||
};
|
||||
return;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
if (sock->tlsstream.nsending == 0) {
|
||||
@@ -451,8 +470,12 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
||||
|
||||
error:
|
||||
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
|
||||
ISC_LOG_ERROR, "SSL error in BIO: %d %s", tls_status,
|
||||
isc_result_totext(result));
|
||||
ISC_LOG_NOTICE,
|
||||
"SSL error in BIO: %d %s (errno: %d). Arguments: "
|
||||
"received_data: %p, "
|
||||
"send_data: %p, finish: %s",
|
||||
tls_status, isc_result_totext(result), saved_errno,
|
||||
received_data, send_data, finish ? "true" : "false");
|
||||
tls_failed_read_cb(sock, result);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user