[PATCH bpf-next v6 2/2] bpftool: Fix bypass of the batch line length check by comments
Yuan Chen <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]>
---
v6: move the line-length checks before comment stripping instead of
detecting truncated reads with memchr()/feof(), as suggested by
Andrii Nakryiko
tools/bpf/bpftool/main.c | 16 ++++++++--------
1 file 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 @@
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 @@
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);
}
--
2.43.0