From 4a999def99902dd6d8911a4ae33ba6d17e7e8082 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Wed, 20 May 2026 09:01:25 +0200 Subject: [PATCH] mbedtls: return error when retrying a blocked send with a shorter buffer mbedtls_ssl_write() requires the retry call after WANT_WRITE to use at least as many bytes as the original blocked call. The DEBUGASSERT enforcing this was compiled out in release builds, leaving the len inflation free to exceed the caller's buffer and produce n > buflen. Replace the assert with an explicit CURLE_SEND_ERROR so the constraint is enforced in release builds too. Document the retry buflen requirement in curl_easy_send(3). --- docs/libcurl/curl_easy_send.md | 4 +++- lib/vtls/mbedtls.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/libcurl/curl_easy_send.md b/docs/libcurl/curl_easy_send.md index 016a6756a8..012831b46b 100644 --- a/docs/libcurl/curl_easy_send.md +++ b/docs/libcurl/curl_easy_send.md @@ -92,7 +92,9 @@ send. On failure, returns the appropriate error code. This function may return **CURLE_AGAIN**. In this case, use your operating -system facilities to wait until the socket is writable, and retry. +system facilities to wait until the socket is writable, and retry. The +**buflen** passed to the retry should be no smaller than the one passed to +the call that returned **CURLE_AGAIN**. If there is no socket available to use from the previous transfer, this function returns **CURLE_UNSUPPORTED_PROTOCOL**. diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index f0d2f80230..1c7831467e 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -1280,7 +1280,8 @@ static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, * loses bytes, e.g. reporting all was sent but they were not. * Remember the blocked length and use that when set. */ if(backend->send_blocked) { - DEBUGASSERT(backend->send_blocked_len <= len); + if(len < backend->send_blocked_len) + return CURLE_SEND_ERROR; CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> previously blocked " "on %zu bytes", len, backend->send_blocked_len); len = backend->send_blocked_len;