Linux Perf Users
 help / color / mirror / Atom feed
* [PATCH v2] perf: Fix off-by-one stack buffer overflow in kallsyms__parse()
@ 2026-05-22  7:07 Rui Qi
  2026-05-26  2:09 ` Namhyung Kim
  0 siblings, 1 reply; 3+ messages in thread
From: Rui Qi @ 2026-05-22  7:07 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim
  Cc: Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
	Adrian Hunter, James Clark, linux-perf-users, linux-kernel,
	Rui Qi

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 sizeof(symbol_name) - 1, 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 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..0f87c654ea63 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 < sizeof(symbol_name) - 1; 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 == sizeof(symbol_name) - 1)
+			read_to_eol(&io);
+
 		err = process_symbol(arg, symbol_name, symbol_type, start);
 		if (err)
 			break;
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] perf: Fix off-by-one stack buffer overflow in kallsyms__parse()
  2026-05-22  7:07 [PATCH v2] perf: Fix off-by-one stack buffer overflow in kallsyms__parse() Rui Qi
@ 2026-05-26  2:09 ` Namhyung Kim
  2026-05-27  7:57   ` [PATCH v3] " Rui Qi
  0 siblings, 1 reply; 3+ messages in thread
From: Namhyung Kim @ 2026-05-26  2:09 UTC (permalink / raw)
  To: Rui Qi
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
	Adrian Hunter, James Clark, linux-perf-users, linux-kernel

On Fri, May 22, 2026 at 03:07:38PM +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 sizeof(symbol_name) - 1, 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 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..0f87c654ea63 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 < sizeof(symbol_name) - 1; 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 == sizeof(symbol_name) - 1)

Then maybe it's more intuitive to check with KSYM_NAME_LEN.

Thanks,
Namhyung


> +			read_to_eol(&io);
> +
>  		err = process_symbol(arg, symbol_name, symbol_type, start);
>  		if (err)
>  			break;
> -- 
> 2.20.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v3] perf: Fix off-by-one stack buffer overflow in kallsyms__parse()
  2026-05-26  2:09 ` Namhyung Kim
@ 2026-05-27  7:57   ` Rui Qi
  0 siblings, 0 replies; 3+ messages in thread
From: Rui Qi @ 2026-05-27  7:57 UTC (permalink / raw)
  To: namhyung
  Cc: peterz, mingo, acme, mark.rutland, alexander.shishkin, jolsa,
	irogers, adrian.hunter, james.clark, linux-perf-users,
	linux-kernel, Rui Qi

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 sizeof(symbol_name) - 1, 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 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..198bfc7c1f63 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 < sizeof(symbol_name) - 1; 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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-27  7:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-22  7:07 [PATCH v2] perf: Fix off-by-one stack buffer overflow in kallsyms__parse() Rui Qi
2026-05-26  2:09 ` Namhyung Kim
2026-05-27  7:57   ` [PATCH v3] " Rui Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox