From 509fbcc4f82e5484d98ce47a83da83ff0a767f81 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Thu, 27 Jun 2024 11:38:09 +0100 Subject: [PATCH] Fix raw TLS overflow for large uploads --- mongoose.c | 24 ++++++++++++++---------- src/sock.c | 24 ++++++++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/mongoose.c b/mongoose.c index e8006f3b..2930a738 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7522,17 +7522,21 @@ static void read_conn(struct mg_connection *c) { size_t len = c->recv.size - c->recv.len; long n = -1; if (c->is_tls) { - if (!ioalloc(c, &c->rtls)) return; - n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], - c->rtls.size - c->rtls.len); - if (n == MG_IO_ERR && c->rtls.len == 0) { - // Close only if we have fully drained both raw (rtls) and TLS buffers - c->is_closing = 1; - } else { - if (n > 0) c->rtls.len += (size_t) n; - if (c->is_tls_hs) mg_tls_handshake(c); - n = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); + // Do not read to the raw TLS buffer if it already has enough. + // This is to prevent overflowing c->rtls if our reads are slow + if (c->rtls.len < 16 * 1024) { // 16k is the max TLS message size + if (!ioalloc(c, &c->rtls)) return; + n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], + c->rtls.size - c->rtls.len); + if (n == MG_IO_ERR && c->rtls.len == 0) { + // Close only if we have fully drained both raw (rtls) and TLS buffers + c->is_closing = 1; + } else { + if (n > 0) c->rtls.len += (size_t) n; + if (c->is_tls_hs) mg_tls_handshake(c); + } } + n = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); } else { n = recv_raw(c, buf, len); } diff --git a/src/sock.c b/src/sock.c index 66a23482..e9583126 100644 --- a/src/sock.c +++ b/src/sock.c @@ -276,17 +276,21 @@ static void read_conn(struct mg_connection *c) { size_t len = c->recv.size - c->recv.len; long n = -1; if (c->is_tls) { - if (!ioalloc(c, &c->rtls)) return; - n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], - c->rtls.size - c->rtls.len); - if (n == MG_IO_ERR && c->rtls.len == 0) { - // Close only if we have fully drained both raw (rtls) and TLS buffers - c->is_closing = 1; - } else { - if (n > 0) c->rtls.len += (size_t) n; - if (c->is_tls_hs) mg_tls_handshake(c); - n = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); + // Do not read to the raw TLS buffer if it already has enough. + // This is to prevent overflowing c->rtls if our reads are slow + if (c->rtls.len < 16 * 1024) { // 16k is the max TLS message size + if (!ioalloc(c, &c->rtls)) return; + n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], + c->rtls.size - c->rtls.len); + if (n == MG_IO_ERR && c->rtls.len == 0) { + // Close only if we have fully drained both raw (rtls) and TLS buffers + c->is_closing = 1; + } else { + if (n > 0) c->rtls.len += (size_t) n; + if (c->is_tls_hs) mg_tls_handshake(c); + } } + n = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len); } else { n = recv_raw(c, buf, len); }