openssl: error on SSL_ERROR_SYSCALL

Convert the debug-only handling of SSL_ERROR_SYSCALL so that it is
enabled in all builds with openssl. This should not make a difference in
supported OpenSSL versions, but if whatever version or fork we link
against *does* return SSL_ERROR_SYSCALL, handle this as a fatal error.

Fixes #17471
Reported-by: Michael Kaufmann
Closes #17531
This commit is contained in:
Stefan Eissing 2025-06-04 11:12:28 +02:00 committed by Daniel Stenberg
parent 5586520745
commit 14b42c89db
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 24 additions and 26 deletions

View file

@ -5364,31 +5364,32 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
nread = -1;
goto out;
}
/* For debug builds be a little stricter and error on any
SSL_ERROR_SYSCALL. For example a server may have closed the connection
abruptly without a close_notify alert. For compatibility with older
peers we do not do this by default. #4624
We can use this to gauge how many users may be affected, and
if it goes ok eventually transition to allow in dev and release with
the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */
#ifdef DEBUGBUILD
if(err == SSL_ERROR_SYSCALL) {
int sockerr = SOCKERRNO;
if(sockerr)
Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
else {
msnprintf(error_buffer, sizeof(error_buffer),
"Connection closed abruptly");
else if(err == SSL_ERROR_SYSCALL) {
if(octx->io_result) {
/* logging handling in underlying filter already */
*curlcode = octx->io_result;
}
else if(connssl->peer_closed) {
failf(data, "Connection closed abruptly");
*curlcode = CURLE_RECV_ERROR;
}
else {
/* We should no longer get here nowadays. But handle
* the error in case of some weirdness in the OSSL stack */
int sockerr = SOCKERRNO;
if(sockerr)
Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
else {
msnprintf(error_buffer, sizeof(error_buffer),
"Connection closed abruptly");
}
failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_RECV_ERROR;
}
failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d"
" (Fatal because this is a curl debug build)",
error_buffer, sockerr);
*curlcode = CURLE_RECV_ERROR;
nread = -1;
goto out;
}
#endif
}
}

View file

@ -2027,8 +2027,7 @@ static ssize_t wssl_recv(struct Curl_cfilter *cf,
}
else if(!wssl->io_result && connssl->peer_closed) {
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen);
*curlcode = CURLE_OK;
return 0;
failf(data, "Connection closed abruptly");
}
else {
char error_buffer[256];

View file

@ -120,9 +120,7 @@ class TestErrors:
r = curl.http_download(urls=[url], alpn_proto=proto, extra_args=[
'--parallel', '--trace-config', 'ssl'
])
if proto == 'http/1.0' and not env.curl_uses_lib('wolfssl') and \
(env.curl_is_debug() or
not env.curl_uses_any_libs(['openssl', 'libressl', 'aws-lc'])):
if proto == 'http/1.0':
# we are inconsistent if we fail or not in missing TLS shutdown
# openssl code ignore such errors intentionally in non-debug builds
r.check_exit_code(56)