summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens2026-03-31 20:56:15 +0000
committerHauke Mehrtens2026-05-15 00:29:10 +0000
commit2c869c094c25e1b6b7c1ba786f22280a6c153447 (patch)
treebc251aae8596e6f04106731e462b73b2394542a3
parent778ccbbf5f8aa90e368100897f59322314287ab4 (diff)
downloaduhttpd-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.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/client.c b/client.c
index 69bb7e1..7f87f2e 100644
--- a/client.c
+++ b/client.c
@@ -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;