[PATCH] powerpc/boot: avoid overflowing the bootwrapper printf buffer with bootargs
R Nageswara Sastry
rnsastry at linux.ibm.com
Mon Apr 13 16:02:23 AEST 2026
On 01.04.2026 9:33 PM, Pengpeng Hou wrote:
> 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 <pengpeng at iscas.ac.cn>
Tested-by: R Nageswara Sastry <rnsastry at linux.ibm.com>
Tested this on Power11 with different sizes of the kernel parameters in
bytes (e.g. 512, 1024, 2047, 2049) not seen any errors/crashes. If some
one wants to test, test with more data in a parameter rather than number
of parameters. In general there is a limit of number of kernel
parameters defined in CONFIG_INIT_ENV_ARG_LIMIT.
> ---
> 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)
--
Thanks and Regards
R.Nageswara Sastry
More information about the Linuxppc-dev
mailing list