[PATCH] sparc32: prom: check OF console path formatting against the early buffer
From: Pengpeng Hou
Date: Fri Apr 17 2026 - 04:08:45 EST
of_console_init() allocates a fixed 256-byte buffer for the console path
and then formats "%pOF" into it with sprintf(), optionally appending
":a" or ":b" with strcat().
The full OF path is not bounded to fit in that early buffer, so the
console path formatting can overrun the allocation before the buffer is
published globally.
Use snprintf()/strlcat() and halt early if the console path does not fit
in the fixed early allocation.
Fixes: c73fcc846c91 ("[SPARC]: Fix serial console device detection.")
Fixes: a412c85aa82a ("sparc: Convert to using %pOF instead of full_name")
Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
arch/sparc/kernel/prom_32.c | 65 +++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 20 deletions(-)
diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c
index cd94f1e8d644..7bfede7e64d2 100644
--- a/arch/sparc/kernel/prom_32.c
+++ b/arch/sparc/kernel/prom_32.c
@@ -245,15 +245,23 @@ void __init of_console_init(void)
if (!dp) {
prom_printf("Cannot find PROM_V0 console node.\n");
prom_halt();
- }
- of_console_device = dp;
+ }
+ of_console_device = dp;
- sprintf(of_console_path, "%pOF", dp);
- if (!strcmp(type, "serial")) {
- strcat(of_console_path,
- (skip ? ":b" : ":a"));
- }
- break;
+ if (snprintf(of_console_path, of_console_path_sz,
+ "%pOF", dp) >= of_console_path_sz) {
+ prom_printf("PROM_V0 console path is too long.\n");
+ prom_halt();
+ }
+ if (!strcmp(type, "serial")) {
+ if (strlcat(of_console_path, skip ? ":b" : ":a",
+ of_console_path_sz) >=
+ of_console_path_sz) {
+ prom_printf("PROM_V0 console path options are too long.\n");
+ prom_halt();
+ }
+ }
+ break;
default:
case PROM_V2:
@@ -279,18 +287,35 @@ void __init of_console_init(void)
prom_halt();
}
- of_console_device = dp;
-
- if (prom_vers == PROM_V2) {
- sprintf(of_console_path, "%pOF", dp);
- switch (*romvec->pv_stdout) {
- case PROMDEV_TTYA:
- strcat(of_console_path, ":a");
- break;
- case PROMDEV_TTYB:
- strcat(of_console_path, ":b");
- break;
- }
+ of_console_device = dp;
+
+ if (prom_vers == PROM_V2) {
+ if (snprintf(of_console_path, of_console_path_sz,
+ "%pOF", dp) >=
+ of_console_path_sz) {
+ prom_printf("PROM_V2 console path is too long.\n");
+ prom_halt();
+ }
+ switch (*romvec->pv_stdout) {
+ case PROMDEV_TTYA:
+ if (strlcat(of_console_path, ":a",
+ of_console_path_sz) >=
+ of_console_path_sz) {
+ prom_printf("%s",
+ "PROM_V2 console path options are too long.\n");
+ prom_halt();
+ }
+ break;
+ case PROMDEV_TTYB:
+ if (strlcat(of_console_path, ":b",
+ of_console_path_sz) >=
+ of_console_path_sz) {
+ prom_printf("%s",
+ "PROM_V2 console path options are too long.\n");
+ prom_halt();
+ }
+ break;
+ }
} else {
const char *path;
--
2.50.1 (Apple Git-155)