]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf: Fix off-by-one stack buffer overflow in kallsyms__parse()
authorRui Qi <qirui.001@bytedance.com>
Thu, 28 May 2026 06:23:55 +0000 (14:23 +0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 4 Jun 2026 13:58:47 +0000 (10:58 -0300)
In kallsyms__parse(), the loop reading symbol names iterates with i <
sizeof(symbol_name), which allows i to reach sizeof(symbol_name) upon
loop exit. The subsequent symbol_name[i] = '\0' then writes one byte
past the end of the stack-allocated symbol_name[] array.

Fix this by changing the loop bound to KSYM_NAME_LEN, so the null
terminator always lands within the array. The overflow is triggerable by
a kallsyms entry with a symbol name of KSYM_NAME_LEN+1 or more
characters (e.g., long Rust mangled names or a malicious
/proc/kallsyms).

Fixes: 53df2b9344128984 ("libsymbols kallsyms: Parse using io api")
Signed-off-by: Rui Qi <qirui.001@bytedance.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/lib/symbol/kallsyms.c

index e335ac2b9e19725790b347e5aee4a30d9f04e738..d64bd9cc82a90ed445097409c2afebf0cf15d64a 100644 (file)
@@ -60,7 +60,7 @@ int kallsyms__parse(const char *filename, void *arg,
                        read_to_eol(&io);
                        continue;
                }
-               for (i = 0; i < sizeof(symbol_name); i++) {
+               for (i = 0; i < KSYM_NAME_LEN; i++) {
                        ch = io__get_char(&io);
                        if (ch < 0 || ch == '\n')
                                break;
@@ -68,6 +68,9 @@ int kallsyms__parse(const char *filename, void *arg,
                }
                symbol_name[i]  = '\0';
 
+               if (i == KSYM_NAME_LEN)
+                       read_to_eol(&io);
+
                err = process_symbol(arg, symbol_name, symbol_type, start);
                if (err)
                        break;