summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Goryavsky <julius.goryavsky@mariadb.com>2023-01-31 09:25:06 +0100
committerJulius Goryavsky <julius.goryavsky@mariadb.com>2023-01-31 09:25:06 +0100
commit11ae4ed4bf1fc3bcacc6d9b92cb7f173b828983a (patch)
tree988a919f55b8a79176cc6c9a5f8dc834eed552e1
parent45087dd0b349062d4924ef932696dc674f10c396 (diff)
downloadmariadb-git-bb-10.10-release-ssl.tar.gz
MDEV-30452: ssl error: unexpected EOF while readingbb-10.10-release-ssl
This commit contains a correction for a new behaviour was introduced in OpenSSL 3.x when a peer does not send close_notify before closing the connection - previously it was reported as an SSL_ERROR_SYSCALL error with a errno == 0, but now it is reported as SSL_ERROR_SSL with a special reason code.
m---------libmariadb0
-rw-r--r--vio/viossl.c49
-rw-r--r--vio/viosslfactories.c29
3 files changed, 46 insertions, 32 deletions
diff --git a/libmariadb b/libmariadb
-Subproject 12bd1d5511fc2ff766ff6256c71b79a95739533
+Subproject 38ab85463c0088ba638ad333d0e0a068ff2a2c8
diff --git a/vio/viossl.c b/vio/viossl.c
index 94c4bcb46cf..f9ad897dccf 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -32,7 +32,7 @@
@param ssl_error The result code of the failed TLS/SSL I/O operation.
*/
-static void ssl_set_sys_error(int ssl_error)
+static void ssl_set_sys_error(int ssl_error, unsigned long err)
{
int error= 0;
@@ -52,6 +52,25 @@ static void ssl_set_sys_error(int ssl_error)
error= SOCKET_EWOULDBLOCK;
break;
case SSL_ERROR_SSL:
+#ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
+ /*
+ Correction for a new behaviour was introduced in OpenSSL 3.x
+ when a peer does not send close_notify before closing the
+ connection - previously it was reported as an SSL_ERROR_SYSCALL
+ error with a errno == 0, but now it is reported as
+ SSL_ERROR_SSL with a special reason code:
+ */
+ if (ERR_GET_REASON(err) == SSL_R_UNEXPECTED_EOF_WHILE_READING)
+ {
+ /* This is not really an fatal error - reset the error code to zero: */
+#ifdef _WIN32
+ WSASetLastError(0);
+#else
+ errno= 0;
+#endif
+ break;
+ }
+#endif
/* Protocol error. */
#ifdef EPROTO
error= EPROTO;
@@ -96,13 +115,14 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event
SSL *ssl= vio->ssl_arg;
my_bool should_retry= TRUE;
+ unsigned long err = ERR_peek_error();
+
#if defined(ERR_LIB_X509) && defined(X509_R_CERT_ALREADY_IN_HASH_TABLE)
/*
Ignore error X509_R_CERT_ALREADY_IN_HASH_TABLE.
This is a workaround for an OpenSSL bug in an older (< 1.1.1)
OpenSSL version.
*/
- unsigned long err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE)
{
@@ -129,7 +149,7 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event
default:
should_retry= FALSE;
*should_wait= FALSE;
- ssl_set_sys_error(ssl_error);
+ ssl_set_sys_error(ssl_error, err);
ERR_clear_error();
break;
}
@@ -233,8 +253,31 @@ int vio_ssl_close(Vio *vio)
*/
break;
default: /* Shutdown failed */
+#ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
+ {
+ unsigned long err= ERR_peek_last_error();
+ int ssl_error= SSL_get_error(ssl, r);
+ /*
+ Correction for a new behaviour was introduced in OpenSSL 3.x
+ when a peer does not send close_notify before closing the
+ connection - previously it was reported as an SSL_ERROR_SYSCALL
+ error with a errno == 0, but now it is reported as
+ SSL_ERROR_SSL with a special reason code:
+ */
+ if (ssl_error == SSL_ERROR_SSL &&
+ (ERR_GET_REASON(err) == SSL_R_UNEXPECTED_EOF_WHILE_READING ||
+ ERR_GET_REASON(err) == SSL_R_SHUTDOWN_WHILE_IN_INIT))
+ {
+ ERR_clear_error();
+ break;
+ }
+ DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %d",
+ ssl_error));
+ }
+#else
DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %d",
SSL_get_error(ssl, r)));
+#endif
break;
}
}
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 289c28d4cf4..9200d8c3ac4 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -233,30 +233,6 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
long ssl_ctx_options;
DBUG_ENTER("new_VioSSLFd");
- /*
- If some optional parameters indicate empty strings, then
- for compatibility with SSL libraries, replace them with NULL,
- otherwise these libraries will try to open files with an empty
- name, etc., and they will return an error code instead performing
- the necessary operations:
- */
- if (ca_file && !ca_file[0])
- {
- ca_file = NULL;
- }
- if (ca_path && !ca_path[0])
- {
- ca_path = NULL;
- }
- if (crl_file && !crl_file[0])
- {
- crl_file = NULL;
- }
- if (crl_path && !crl_path[0])
- {
- crl_path = NULL;
- }
-
DBUG_PRINT("enter",
("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' "
"cipher: '%s' crl_file: '%s' crl_path: '%s'",
@@ -406,11 +382,6 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
struct st_VioSSLFd *ssl_fd;
int verify= SSL_VERIFY_PEER;
- if (ca_file && ! ca_file[0]) ca_file = NULL;
- if (ca_path && ! ca_path[0]) ca_path = NULL;
- if (crl_file && ! crl_file[0]) crl_file = NULL;
- if (crl_path && ! crl_path[0]) crl_path = NULL;
-
/*
If some optional parameters indicate empty strings, then
for compatibility with SSL libraries, replace them with NULL,