From 259670055aea1407090c46cd1df2f0d720fb8db7 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 21 Oct 2025 14:13:41 +0100 Subject: [PATCH] Bound buffered HTTP body size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clamp per-chunk and aggregated HTTP response sizes before allocating in wolfIO_HttpProcessResponseBuf so untrusted Content-Length or chunk headers can’t overflow the arithmetic or force giant buffers. --- src/wolfio.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/wolfio.c b/src/wolfio.c index 16663e34d..42b02f9e5 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1670,12 +1670,17 @@ int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, return result; } +#ifndef WOLFIO_HTTP_MAX_BODY +/* Upper bound on an HTTP body that will be buffered in memory. */ +#define WOLFIO_HTTP_MAX_BODY (32 * 1024 * 1024) +#endif + static int wolfIO_HttpProcessResponseBuf(WolfSSLGenericIORecvCb ioCb, void* ioCbCtx, byte **recvBuf, int* recvBufSz, int chunkSz, char* start, int len, int dynType, void* heap) { byte* newRecvBuf = NULL; - int newRecvSz = *recvBufSz + chunkSz; + int newRecvSz; int pos = 0; WOLFSSL_MSG("Processing HTTP response"); @@ -1691,6 +1696,23 @@ static int wolfIO_HttpProcessResponseBuf(WolfSSLGenericIORecvCb ioCb, return MEMORY_E; } + if (chunkSz > WOLFIO_HTTP_MAX_BODY) { + WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf chunk too large"); + return BUFFER_ERROR; + } + + if (*recvBufSz < 0 || *recvBufSz > WOLFIO_HTTP_MAX_BODY - chunkSz) { + WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf aggregate body too large"); + return BUFFER_ERROR; + } + + if (len > chunkSz) { + WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf len exceeds chunk size"); + return WOLFSSL_FATAL_ERROR; + } + + newRecvSz = *recvBufSz + chunkSz; + if (newRecvSz <= 0) { WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf new receive size overflow"); return MEMORY_E;