Re: [PATCH v6 08/22] bootconfig: init: Allow admin to use bootconfig for init command line
From: Kees Cook <hidden>
Date: 2020-02-07 18:03:21
Also in:
linux-fsdevel, lkml
On Sat, Jan 11, 2020 at 01:04:55AM +0900, Masami Hiramatsu wrote:
quoted hunk ↗ jump to hunk
Since the current kernel command line is too short to describe long and many options for init (e.g. systemd command line options), this allows admin to use boot config for init command line. All init command line under "init." keywords will be passed to init. For example, init.systemd { unified_cgroup_hierarchy = 1 debug_shell default_timeout_start_sec = 60 } Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- init/main.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-)diff --git a/init/main.c b/init/main.c index c0017d9d16e7..dd7da62d99a5 100644 --- a/init/main.c +++ b/init/main.c@@ -139,6 +139,8 @@ char *saved_command_line; static char *static_command_line; /* Untouched extra command line */ static char *extra_command_line; +/* Extra init arguments */ +static char *extra_init_args; static char *execute_command; static char *ramdisk_execute_command;@@ -372,6 +374,8 @@ static void __init setup_boot_config(void) pr_info("Load boot config: %d bytes\n", size); /* keys starting with "kernel." are passed via cmdline */ extra_command_line = xbc_make_cmdline("kernel"); + /* Also, "init." keys are init arguments */ + extra_init_args = xbc_make_cmdline("init"); } } #else@@ -507,16 +511,18 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { } */ static void __init setup_command_line(char *command_line) { - size_t len, xlen = 0; + size_t len, xlen = 0, ilen = 0; if (extra_command_line) xlen = strlen(extra_command_line); + if (extra_init_args) + ilen = strlen(extra_init_args) + 4; /* for " -- " */ len = xlen + strlen(boot_command_line) + 1; - saved_command_line = memblock_alloc(len, SMP_CACHE_BYTES); + saved_command_line = memblock_alloc(len + ilen, SMP_CACHE_BYTES); if (!saved_command_line) - panic("%s: Failed to allocate %zu bytes\n", __func__, len); + panic("%s: Failed to allocate %zu bytes\n", __func__, len + ilen); static_command_line = memblock_alloc(len, SMP_CACHE_BYTES); if (!static_command_line)@@ -533,6 +539,22 @@ static void __init setup_command_line(char *command_line) } strcpy(saved_command_line + xlen, boot_command_line); strcpy(static_command_line + xlen, command_line); + + if (ilen) { + /* + * Append supplemental init boot args to saved_command_line + * so that user can check what command line options passed + * to init. + */ + len = strlen(saved_command_line); + if (!strstr(boot_command_line, " -- ")) { + strcpy(saved_command_line + len, " -- "); + len += 4; + } else + saved_command_line[len++] = ' '; + + strcpy(saved_command_line + len, extra_init_args); + }
This isn't safe because it will destroy any argument with " -- " in quotes and anything after it. For example, booting with: thing=on acpi_osi="! -- " other=setting will wreck acpi_osi's value and potentially overwrite "other=settings", etc. (Yes, this seems very unlikely, but you can't treat " -- " as special, the command line string must be correct parsed for double quotes, as parse_args() does.)
quoted hunk ↗ jump to hunk
} /*@@ -759,6 +781,9 @@ asmlinkage __visible void __init start_kernel(void) if (!IS_ERR_OR_NULL(after_dashes)) parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, NULL, set_init_arg); + if (extra_init_args) + parse_args("Setting extra init args", extra_init_args, + NULL, 0, -1, -1, NULL, set_init_arg);
Here is where you can append the extra_init_args, since parse_args() will have done the work to find after_dashes correctly. -Kees
/* * These use large bootmem allocations and must precede
-- Kees Cook