Browse Source

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 <jan-niklas.sohn@gmx.de>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich 4 years ago
parent
commit
5f9ae57383
1 changed files with 2 additions and 2 deletions
  1. 2 2
      client.c

+ 2 - 2
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;