diff options
| author | Hauke Mehrtens | 2026-04-09 20:21:55 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-18 22:06:49 +0000 |
| commit | afc0fa8680e2076af534c5ebc4dd73f5d8658e25 (patch) | |
| tree | 59b38584963ffc296bbb42b02b7a11a13d6637a8 | |
| parent | 320322291ece1db97c5b05ceb97fd0f5776c5398 (diff) | |
| download | libubox-afc0fa8680e2076af534c5ebc4dd73f5d8658e25.tar.gz | |
blobmsg_json: fix integer overflow in blobmsg_puts()
The strbuf struct used 'int' for its len and pos fields, and
blobmsg_puts() took an 'int' len parameter. When formatting very
large JSON structures, the check 's->pos + len >= s->len' could
overflow, wrapping to a negative value. This caused the bounds
check to be bypassed, leading to a heap buffer overflow as data
was written past the allocated buffer without triggering a realloc.
Fix this by changing the strbuf len/pos fields and the blobmsg_puts()
len parameter to size_t, and restructuring the bounds check as
's->len - s->pos <= len' to avoid overflow entirely.
Link: https://github.com/openwrt/libubox/pull/42
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
(cherry picked from commit 700eca0bac660268369ed7c77241a74971a67ee6)
| -rw-r--r-- | blobmsg_json.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/blobmsg_json.c b/blobmsg_json.c index 31eec09..0fa5d85 100644 --- a/blobmsg_json.c +++ b/blobmsg_json.c @@ -112,8 +112,8 @@ bool blobmsg_add_json_from_string(struct blob_buf *b, const char *str) struct strbuf { - int len; - int pos; + size_t len; + size_t pos; char *buf; blobmsg_json_format_t custom_format; @@ -122,15 +122,15 @@ struct strbuf { int indent_level; }; -static bool blobmsg_puts(struct strbuf *s, const char *c, int len) +static bool blobmsg_puts(struct strbuf *s, const char *c, size_t len) { size_t new_len; char *new_buf; - if (len <= 0) + if (!len) return true; - if (s->pos + len >= s->len) { + if (s->len - s->pos <= len) { new_len = s->len + 16 + len; new_buf = realloc(s->buf, new_len); if (!new_buf) @@ -170,7 +170,7 @@ static void blobmsg_format_string(struct strbuf *s, const char *str) blobmsg_puts(s, "\"", 1); for (p = (unsigned char *) str, last = p; *p; p++) { char escape = '\0'; - int len; + size_t len; switch(*p) { case '\b': |