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


Reply via email to