From: Daniel Stenberg Date: Mon, 22 Sep 2025 09:27:27 +0000 (+0200) Subject: mbedtls: handle WANT_WRITE from mbedtls_ssl_read() X-Git-Tag: rc-8_17_0-1~257 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0f1657ca75fcca4dbdbccf31d9d6cf4fae4a98e5;p=thirdparty%2Fcurl.git mbedtls: handle WANT_WRITE from mbedtls_ssl_read() The mbedtls_ssl_read() function is documented to be able to also return MBEDTLS_ERR_SSL_WANT_WRITE, so act on that accordingly instead of returning error for it. Assisted-by: Stefan Eissing Reported in Joshua's sarif data Closes #18682 --- diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index a8abd0fe09..0a62da2b58 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -1113,8 +1113,9 @@ static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, int nwritten; (void)data; - *pnwritten = 0; DEBUGASSERT(backend); + *pnwritten = 0; + connssl->io_need = CURL_SSL_IO_NEED_NONE; /* mbedtls is picky when a mbedtls_ssl_write) was previously blocked. * It requires to be called with the same amount of bytes again, or it * will lose bytes, e.g. reporting all was sent but they were not. @@ -1135,11 +1136,22 @@ static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, else { CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X", len, -nwritten); - result = ((nwritten == MBEDTLS_ERR_SSL_WANT_WRITE) + switch(nwritten) { #ifdef MBEDTLS_SSL_PROTO_TLS1_3 - || (nwritten == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET: #endif - ) ? CURLE_AGAIN : CURLE_SEND_ERROR; + case MBEDTLS_ERR_SSL_WANT_READ: + connssl->io_need = CURL_SSL_IO_NEED_RECV; + result = CURLE_AGAIN; + break; + case MBEDTLS_ERR_SSL_WANT_WRITE: + connssl->io_need = CURL_SSL_IO_NEED_SEND; + result = CURLE_AGAIN; + break; + default: + result = CURLE_SEND_ERROR; + break; + } if((result == CURLE_AGAIN) && !backend->send_blocked) { backend->send_blocked = TRUE; backend->send_blocked_len = len; @@ -1280,6 +1292,7 @@ static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data, (void)data; DEBUGASSERT(backend); *pnread = 0; + connssl->io_need = CURL_SSL_IO_NEED_NONE; nread = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, buffersize); if(nread > 0) @@ -1294,6 +1307,11 @@ static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data, FALLTHROUGH(); #endif case MBEDTLS_ERR_SSL_WANT_READ: + connssl->io_need = CURL_SSL_IO_NEED_RECV; + result = CURLE_AGAIN; + break; + case MBEDTLS_ERR_SSL_WANT_WRITE: + connssl->io_need = CURL_SSL_IO_NEED_SEND; result = CURLE_AGAIN; break; case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: