mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 15:45:25 +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.
|
* information regarding copyright ownership.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <uv.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;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
int pending, tls_status = SSL_ERROR_NONE;
|
int pending, tls_status = SSL_ERROR_NONE;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
bool sent_shutdown = false, received_shutdown = false;
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
int saved_errno = 0;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
REQUIRE(sock->tid == isc_nm_tid());
|
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);
|
received_data->length, &len);
|
||||||
if (rv <= 0 || len != received_data->length) {
|
if (rv <= 0 || len != received_data->length) {
|
||||||
result = ISC_R_TLSERROR;
|
result = ISC_R_TLSERROR;
|
||||||
|
saved_errno = errno;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +374,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
|||||||
} else if (send_data != NULL) {
|
} else if (send_data != NULL) {
|
||||||
INSIST(received_data == NULL);
|
INSIST(received_data == NULL);
|
||||||
INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
|
INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
|
||||||
received_shutdown =
|
bool received_shutdown =
|
||||||
((SSL_get_shutdown(sock->tlsstream.tls) &
|
((SSL_get_shutdown(sock->tlsstream.tls) &
|
||||||
SSL_RECEIVED_SHUTDOWN) != 0);
|
SSL_RECEIVED_SHUTDOWN) != 0);
|
||||||
rv = SSL_write_ex(sock->tlsstream.tls,
|
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);
|
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);
|
pending = tls_process_outgoing(sock, finish, send_data);
|
||||||
if (pending > 0) {
|
if (pending > 0) {
|
||||||
@@ -420,11 +444,6 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
|||||||
switch (tls_status) {
|
switch (tls_status) {
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
if (sent_shutdown && received_shutdown) {
|
|
||||||
/* clean shutdown */
|
|
||||||
isc_nm_cancelread(sock->outerhandle);
|
|
||||||
isc__nm_tls_close(sock);
|
|
||||||
};
|
|
||||||
return;
|
return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
if (sock->tlsstream.nsending == 0) {
|
if (sock->tlsstream.nsending == 0) {
|
||||||
@@ -451,8 +470,12 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
|
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
|
||||||
ISC_LOG_ERROR, "SSL error in BIO: %d %s", tls_status,
|
ISC_LOG_NOTICE,
|
||||||
isc_result_totext(result));
|
"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);
|
tls_failed_read_cb(sock, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user