cmdline_contains is used by BPF selftests to check the presence of specific kernel commandline parameters, but it currently suffers from two issues: - the read commandline isn't NULL terminated right after the read data but only at the end of the buffer, leaving uninitialized bytes that are then possibly tokenized - the comparison of found tokens is done based on the size of found token. This could lead to too-short-but-matching tokens to wrongly match the search pattern.
Enforce stricter checks in cmdline_contains to avoid accidental matches. Signed-off-by: Alexis Lothoré (eBPF Foundation) <[email protected]> --- tools/testing/selftests/bpf/unpriv_helpers.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/bpf/unpriv_helpers.c b/tools/testing/selftests/bpf/unpriv_helpers.c index f997d7ec8fd0..c99d81df2aa2 100644 --- a/tools/testing/selftests/bpf/unpriv_helpers.c +++ b/tools/testing/selftests/bpf/unpriv_helpers.c @@ -72,8 +72,9 @@ static int config_contains(const char *pat) static bool cmdline_contains(const char *pat) { + int fd, cnt, ret = false; char cmdline[4096], *c; - int fd, ret = false; + size_t pat_len; fd = open("/proc/cmdline", O_RDONLY); if (fd < 0) { @@ -81,14 +82,16 @@ static bool cmdline_contains(const char *pat) return false; } - if (read(fd, cmdline, sizeof(cmdline) - 1) < 0) { + cnt = read(fd, cmdline, sizeof(cmdline) - 1); + if (cnt < 0) { perror("read /proc/cmdline"); goto out; } - cmdline[sizeof(cmdline) - 1] = '\0'; + cmdline[cnt] = '\0'; + pat_len = strlen(pat); for (c = strtok(cmdline, " \n"); c; c = strtok(NULL, " \n")) { - if (strncmp(c, pat, strlen(c))) + if (strlen(c) != pat_len || strcmp(c, pat)) continue; ret = true; break; -- 2.55.0

