From eeef7529c0be4f7a40fdfbacde5629b6c1d4e41a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Jun 2026 09:41:06 +0200 Subject: [PATCH] options: clamp snprintf length before err_buf[len] write in parse_size_arg C99 snprintf returns the would-have-written length on truncation, so when a daemon client sends an oversized --max-size/--min-size/--bwlimit/--block-size/ --max-alloc value (each arg can be up to BIGPATHBUFLEN-1 = 5119 bytes via clientserver.c:read_args), len at the failure: label can far exceed sizeof err_buf (200). The trailing err_buf[len] = '\n'; err_buf[len+1] = '\0'; then write 0x0A,0x00 at a byte-precise attacker-chosen offset up to ~4.9KB past err_buf into adjacent .bss. The same happens via the second snprintf when the first lands len in [~140,189] and the (min/max: ...) suffix is truncated. Clamp len to sizeof err_buf - 2 before the trailing writes, covering both paths. Reachable from an unauthenticated client against any daemon module before chroot/privilege-drop; introduced in 66ca4fc97bced (2020-07-10). (cherry picked from commit 3b81103d7ec98145710f8845dd676ba34458169a) (cherry picked from commit ada5da09e238aa97cb5b438a8601e18d75105d05) --- options.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options.c b/options.c index 80c0c6a3..3becae13 100644 --- a/options.c +++ b/options.c @@ -1176,6 +1176,8 @@ failure: min_max, do_big_num(limit, 3, NULL), unlimited_0 && min_max[1] == 'i' ? " or 0 for unlimited" : ""); } + if (len < 0 || len > (int)sizeof err_buf - 2) + len = sizeof err_buf - 2; err_buf[len] = '\n'; err_buf[len+1] = '\0'; return -1;