diff options
| author | Yuan Chen <chenyuan_fl@163.com> | 2026-08-24 17:26:57 +0800 |
|---|---|---|
| committer | Andrii Nakryiko <andrii@kernel.org> | 2026-08-27 17:07:31 -0700 |
| commit | ac3d88577cdaa5330cf32d03ee3808df8fa338ac (patch) | |
| tree | 9b95d5bee6ee1972cb7608a1086e32d73a9ecac1 | |
| parent | 713c02b59e21840f623a3e31c43d967026c75181 (diff) | |
| download | linux-next-ac3d88577cdaa5330cf32d03ee3808df8fa338ac.tar.gz linux-next-ac3d88577cdaa5330cf32d03ee3808df8fa338ac.zip | |
bpftool: Fix bypass of the batch line length check by comments
do_batch() strips trailing comments by truncating the line at '#'
before checking whether fgets() filled the buffer. If a batch line
longer than the buffer contains a '#' within the first
sizeof(buf) - 1 bytes, the truncation makes strlen(buf) smaller and the
line-length check is bypassed. The unread remainder of the line then
stays in the file stream and is parsed and executed as a separate
command on the next loop iteration.
Continuation lines handled below are affected the same way: an overlong
continuation line containing '#' bypasses the "command is too long"
check, and its unread remainder is executed as a separate command.
Move the line-length checks before the comment is stripped, so they see
the full line as read from the file and overlong lines are rejected
regardless of comments. A line that fills the buffer exactly is now
rejected as well, which is fine: batch command lines are not expected
to come anywhere near the buffer limit.
Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool")
Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260824092657.1789956-3-chenyuan_fl@163.com
| -rw-r--r-- | tools/bpf/bpftool/main.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index 7a0c214f08a0..5ababd8f7d0a 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -370,15 +370,15 @@ static int do_batch(int argc, char **argv) if (!fgets(buf, sizeof(buf), fp)) break; - cp = strchr(buf, '#'); - if (cp) - *cp = '\0'; - if (strlen(buf) == sizeof(buf) - 1) { errno = E2BIG; break; } + cp = strchr(buf, '#'); + if (cp) + *cp = '\0'; + /* Append continuation lines if any (coming after a line ending * with '\' in the batch file). */ @@ -391,15 +391,15 @@ static int do_batch(int argc, char **argv) goto err_close; } - cp = strchr(contline, '#'); - if (cp) - *cp = '\0'; - if (strlen(buf) + strlen(contline) + 1 > sizeof(buf)) { p_err("command %u is too long", lines); err = -1; goto err_close; } + + cp = strchr(contline, '#'); + if (cp) + *cp = '\0'; buf[strlen(buf) - 2] = '\0'; strcat(buf, contline); } |
