From: Jo-Philipp Wich Date: Sun, 22 Dec 2019 21:32:00 +0000 (+0100) Subject: client: fix invalid data access through invalid content-length values X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=5f9ae5738372aaa3a6be2f0a278933563d3f191a;p=oweals%2Fuhttpd.git client: fix invalid data access through invalid content-length values An invalid data access can be triggered with an HTTP POST request to a CGI script specifying both `Transfer-Encoding: chunked` and a large negative `Content-Length`. The negative content length is assigned to `r->content_length` in `client_parse_header` and passed as a negative read length to `ustream_consume` in `client_poll_post_data` which will set the internal ustream buffer pointer to an invalid address, causing out of bounds memory reads later on in the code flow. A similar implicit unsigned to signed conversion happens when parsing chunk sizes emitted by a CGI program. Address these issues by rejecting negative values in `r->content_length` after assigning the `strtoul()` result. Reported-by: Jan-Niklas Sohn Signed-off-by: Jo-Philipp Wich --- diff --git a/client.c b/client.c index 5913553..92f7609 100644 --- a/client.c +++ b/client.c @@ -346,7 +346,7 @@ static void client_parse_header(struct client *cl, char *data) } } else if (!strcmp(data, "content-length")) { r->content_length = strtoul(val, &err, 0); - if (err && *err) { + if ((err && *err) || r->content_length < 0) { uh_header_error(cl, 400, "Bad Request"); return; } @@ -444,7 +444,7 @@ void client_poll_post_data(struct client *cl) ustream_consume(cl->us, sep + 2 - buf); /* invalid chunk length */ - if (sep && *sep) { + if ((sep && *sep) || r->content_length < 0) { r->content_length = 0; r->transfer_chunked = 0; break;