The bootwrapper printf path formats strings through a fixed 1024-byte scratch buffer in arch/powerpc/boot/stdio.c.
Both prep_cmdline() in main.c and ps3.c print the full bootargs string with a %s conversion even though the command line buffer itself is 2048 bytes. A long firmware-provided or built-in command line can therefore overrun the bootwrapper printf staging buffer while the kernel is still starting. Print the command line through console_ops.write() in bounded chunks instead of passing it to printf() as a single %s argument. Signed-off-by: Pengpeng Hou <[email protected]> --- arch/powerpc/boot/main.c | 12 +++++++++++- arch/powerpc/boot/ps3.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 2c0e2a1cab01..d02f77ad4df7 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -193,6 +193,16 @@ static inline void prep_esm_blob(struct addr_range vmlinux, void *chosen) { } static char cmdline[BOOT_COMMAND_LINE_SIZE] __attribute__((__section__("__builtin_cmdline"))); +static void print_cmdline(const char *prefix, const char *suffix) +{ + size_t len = strnlen(cmdline, BOOT_COMMAND_LINE_SIZE - 1); + + printf("%s", prefix); + if (console_ops.write && len) + console_ops.write(cmdline, len); + printf("%s", suffix); +} + static void prep_cmdline(void *chosen) { unsigned int getline_timeout = 5000; @@ -207,7 +217,7 @@ static void prep_cmdline(void *chosen) if (cmdline[0] == '\0') getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); - printf("\n\rLinux/PowerPC load: %s", cmdline); + print_cmdline("\n\rLinux/PowerPC load: ", ""); /* If possible, edit the command line */ if (console_ops.edit_cmdline && getline_timeout) diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c index 89ff46b8b225..2f17b99c713c 100644 --- a/arch/powerpc/boot/ps3.c +++ b/arch/powerpc/boot/ps3.c @@ -31,6 +31,16 @@ BSS_STACK(4096); static char cmdline[BOOT_COMMAND_LINE_SIZE] __attribute__((__section__("__builtin_cmdline"))); +static void print_cmdline(const char *prefix, const char *suffix) +{ + size_t len = strnlen(cmdline, BOOT_COMMAND_LINE_SIZE - 1); + + printf("%s", prefix); + if (console_ops.write && len) + console_ops.write(cmdline, len); + printf("%s", suffix); +} + static void prep_cmdline(void *chosen) { if (cmdline[0] == '\0') @@ -38,7 +48,7 @@ static void prep_cmdline(void *chosen) else setprop_str(chosen, "bootargs", cmdline); - printf("cmdline: '%s'\n", cmdline); + print_cmdline("cmdline: '", "'\n"); } static void ps3_console_write(const char *buf, int len) -- 2.50.1 (Apple Git-155)
