diff options
| author | Hauke Mehrtens | 2026-03-31 20:56:15 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-05-15 00:29:10 +0000 |
| commit | 2c869c094c25e1b6b7c1ba786f22280a6c153447 (patch) | |
| tree | bc251aae8596e6f04106731e462b73b2394542a3 | |
| parent | 778ccbbf5f8aa90e368100897f59322314287ab4 (diff) | |
| download | uhttpd-2c869c094c25e1b6b7c1ba786f22280a6c153447.tar.gz | |
client: parse Content-Length safely
content_length is declared int but the previous strtoul cast silently
wrapped negative inputs into huge positive values, making the < 0
guard unreachable. Switching to strtol exposes negatives, but on
64-bit platforms a value above INT_MAX still passes strtol's own
range check and truncates implementation-defined when narrowed to int.
Parse into a long, check errno for strtol overflow, and reject any
value above INT_MAX or below zero before assigning. The error path
returns 400 Bad Request as before.
Pull in errno.h and limits.h for the new checks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
| -rw-r--r-- | client.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -19,6 +19,8 @@ #include <libubox/blobmsg.h> #include <ctype.h> +#include <errno.h> +#include <limits.h> #include "uhttpd.h" #include "tls.h" @@ -391,11 +393,15 @@ static void client_parse_header(struct client *cl, char *data) return; } } else if (!strcmp(data, "content-length")) { - r->content_length = strtoul(val, &err, 10); - if ((err && *err) || r->content_length < 0) { + long length; + + errno = 0; + length = strtol(val, &err, 10); + if ((err && *err) || errno || length < 0 || length > INT_MAX) { uh_header_error(cl, 400, "Bad Request"); return; } + r->content_length = (int)length; } else if (!strcmp(data, "transfer-encoding")) { if (!strcmp(val, "chunked")) r->transfer_chunked = true; |