tools/lib/symbol/kallsyms.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
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: 53df2b934412 ("libsymbols kallsyms: Parse using io api")
Signed-off-by: Rui Qi <qirui.001@bytedance.com>
---
Changes in v4:
- Use KSYM_NAME_LEN for the loop bound as well, as suggested by Namhyung.
Changes in v3:
- Use KSYM_NAME_LEN instead of sizeof(symbol_name) - 1 for the
overflow check, as suggested by Namhyung.
Changes in v2:
- Added read_to_eol(&io) when a symbol name exceeds the buffer size,
preventing remaining characters from being parsed as the next symbol entry.
- Added Fixes tag.
---
tools/lib/symbol/kallsyms.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c
index e335ac2b9e19..d64bd9cc82a9 100644
--- a/tools/lib/symbol/kallsyms.c
+++ b/tools/lib/symbol/kallsyms.c
@@ -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;
--
2.20.1
On Thu, May 28, 2026 at 02:23:55PM +0800, Rui Qi wrote:
> 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: 53df2b934412 ("libsymbols kallsyms: Parse using io api")
> Signed-off-by: Rui Qi <qirui.001@bytedance.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Thanks,
Namhyung
>
> ---
>
> Changes in v4:
> - Use KSYM_NAME_LEN for the loop bound as well, as suggested by Namhyung.
>
> Changes in v3:
> - Use KSYM_NAME_LEN instead of sizeof(symbol_name) - 1 for the
> overflow check, as suggested by Namhyung.
>
> Changes in v2:
> - Added read_to_eol(&io) when a symbol name exceeds the buffer size,
> preventing remaining characters from being parsed as the next symbol entry.
> - Added Fixes tag.
> ---
> tools/lib/symbol/kallsyms.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c
> index e335ac2b9e19..d64bd9cc82a9 100644
> --- a/tools/lib/symbol/kallsyms.c
> +++ b/tools/lib/symbol/kallsyms.c
> @@ -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;
> --
> 2.20.1
On Thu, May 28, 2026 at 10:34:55AM -0700, Namhyung Kim wrote:
> On Thu, May 28, 2026 at 02:23:55PM +0800, Rui Qi wrote:
> > 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: 53df2b934412 ("libsymbols kallsyms: Parse using io api")
> > Signed-off-by: Rui Qi <qirui.001@bytedance.com>
>
> Acked-by: Namhyung Kim <namhyung@kernel.org>
Thanks, applied to perf-tools-next, for v7.2.
- Arnaldo
© 2016 - 2026 Red Hat, Inc.