Re: [PATCH 03/28] ARM: atags: Replace strlcat() with snprintf() for cmdline extend

From: Kees Cook

Date: Tue Sep 15 2026 - 15:04:45 EST


On Tue, Sep 15, 2026 at 08:18:20AM +0000, Bill Wendling wrote:
> --- a/arch/arm/kernel/atags_parse.c
> +++ b/arch/arm/kernel/atags_parse.c
> @@ -121,9 +121,10 @@ __tagtable(ATAG_REVISION, parse_tag_revision);
> static int __init parse_tag_cmdline(const struct tag *tag)
> {
> #if defined(CONFIG_CMDLINE_EXTEND)
> - strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
> - strlcat(default_command_line, tag->u.cmdline.cmdline,
> - COMMAND_LINE_SIZE);
> + size_t len = strlen(default_command_line);
> +
> + snprintf(default_command_line + len, COMMAND_LINE_SIZE - len,
> + " %s", tag->u.cmdline.cmdline);
> #elif defined(CONFIG_CMDLINE_FORCE)
> pr_warn("Ignoring tag cmdline (using the default kernel command line)\n");
> #else

It's pretty clear we have a pattern of "simple append" that is needed,
and while strlcat() does that, it's horrible. I feel like we need an
appending scnprintf(), and it needs to return like strscpy() does (i.e.
-E2BIG on truncation).

My goal would be:

- don't open-code string length math
- never leave the destination unterminated
- allow for format strings
- yes/no return indication for "did this truncate?"

Initializing a whole seq_buf struct for these small cases is too much
overhead...

For both cases (small without seq_buf, large with seq_buf), it is also
frequently needed to know the resulting strlen. seq_buf doesn't do this
right today, and a strscpy-style return value also doesn't tell us. :(

--
Kees Cook