summaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2020-02-04 15:33:53 +0300
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2020-02-05 12:22:43 +0300
commit7495e0926fdf302cb9e62a49f7c22198815624cd (patch)
tree4c3fb757786ce82fe314227f128d673080d55cc3 /init
parent2b90927c77c973771cc658d639724d5b247a83eb (diff)
downloadlinux-7495e0926fdf302cb9e62a49f7c22198815624cd.tar.xz
bootconfig: Only load bootconfig if "bootconfig" is on the kernel cmdline
As the bootconfig is appended to the initrd it is not as easy to modify as the kernel command line. If there's some issue with the kernel, and the developer wants to boot a pristine kernel, it should not be needed to modify the initrd to remove the bootconfig for a single boot. As bootconfig is silently added (if the admin does not know where to look they may not know it's being loaded). It should be explicitly added to the kernel cmdline. The loading of the bootconfig is only done if "bootconfig" is on the kernel command line. This will let admins know that the kernel command line is extended. Note, after adding printk()s for when the size is too great or the checksum is wrong, exposed that the current method always looked for the boot config, and if this size and checksum matched, it would parse it (as if either is wrong a printk has been added to show this). It's better to only check this if the boot config is asked to be looked for. Link: https://lore.kernel.org/r/CAHk-=wjfjO+h6bQzrTf=YCZA53Y3EDyAs3Z4gEsT7icA3u_Psw@mail.gmail.com Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'init')
-rw-r--r--init/main.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/init/main.c b/init/main.c
index dd7da62d99a5..f174a59d3903 100644
--- a/init/main.c
+++ b/init/main.c
@@ -336,28 +336,39 @@ u32 boot_config_checksum(unsigned char *p, u32 size)
return ret;
}
-static void __init setup_boot_config(void)
+static void __init setup_boot_config(const char *cmdline)
{
u32 size, csum;
char *data, *copy;
+ const char *p;
u32 *hdr;
- if (!initrd_end)
+ p = strstr(cmdline, "bootconfig");
+ if (!p || (p != cmdline && !isspace(*(p-1))) ||
+ (p[10] && !isspace(p[10])))
return;
+ if (!initrd_end)
+ goto not_found;
+
hdr = (u32 *)(initrd_end - 8);
size = hdr[0];
csum = hdr[1];
- if (size >= XBC_DATA_MAX)
+ if (size >= XBC_DATA_MAX) {
+ pr_err("bootconfig size %d greater than max size %d\n",
+ size, XBC_DATA_MAX);
return;
+ }
data = ((void *)hdr) - size;
if ((unsigned long)data < initrd_start)
- return;
+ goto not_found;
- if (boot_config_checksum((unsigned char *)data, size) != csum)
+ if (boot_config_checksum((unsigned char *)data, size) != csum) {
+ pr_err("bootconfig checksum failed\n");
return;
+ }
copy = memblock_alloc(size + 1, SMP_CACHE_BYTES);
if (!copy) {
@@ -377,9 +388,12 @@ static void __init setup_boot_config(void)
/* Also, "init." keys are init arguments */
extra_init_args = xbc_make_cmdline("init");
}
+ return;
+not_found:
+ pr_err("'bootconfig' found on command line, but no bootconfig found\n");
}
#else
-#define setup_boot_config() do { } while (0)
+#define setup_boot_config(cmdline) do { } while (0)
#endif
/* Change NUL term back to "=", to make "param" the whole string. */
@@ -760,7 +774,7 @@ asmlinkage __visible void __init start_kernel(void)
pr_notice("%s", linux_banner);
early_security_init();
setup_arch(&command_line);
- setup_boot_config();
+ setup_boot_config(command_line);
setup_command_line(command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();