[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