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.comAcked-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Suggested-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 2b90927c
...@@ -123,6 +123,8 @@ To remove the config from the image, you can use -d option as below:: ...@@ -123,6 +123,8 @@ To remove the config from the image, you can use -d option as below::
# tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z
Then add "bootconfig" on the normal kernel command line to tell the
kernel to look for the bootconfig at the end of the initrd file.
Config File Limitation Config File Limitation
====================== ======================
......
...@@ -437,6 +437,12 @@ ...@@ -437,6 +437,12 @@
no delay (0). no delay (0).
Format: integer Format: integer
bootconfig [KNL]
Extended command line options can be added to an initrd
and this will cause the kernel to look for it.
See Documentation/admin-guide/bootconfig.rst
bert_disable [ACPI] bert_disable [ACPI]
Disable BERT OS support on buggy BIOSes. Disable BERT OS support on buggy BIOSes.
......
...@@ -336,28 +336,39 @@ u32 boot_config_checksum(unsigned char *p, u32 size) ...@@ -336,28 +336,39 @@ u32 boot_config_checksum(unsigned char *p, u32 size)
return ret; return ret;
} }
static void __init setup_boot_config(void) static void __init setup_boot_config(const char *cmdline)
{ {
u32 size, csum; u32 size, csum;
char *data, *copy; char *data, *copy;
const char *p;
u32 *hdr; u32 *hdr;
if (!initrd_end) p = strstr(cmdline, "bootconfig");
if (!p || (p != cmdline && !isspace(*(p-1))) ||
(p[10] && !isspace(p[10])))
return; return;
if (!initrd_end)
goto not_found;
hdr = (u32 *)(initrd_end - 8); hdr = (u32 *)(initrd_end - 8);
size = hdr[0]; size = hdr[0];
csum = hdr[1]; 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; return;
}
data = ((void *)hdr) - size; data = ((void *)hdr) - size;
if ((unsigned long)data < initrd_start) 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; return;
}
copy = memblock_alloc(size + 1, SMP_CACHE_BYTES); copy = memblock_alloc(size + 1, SMP_CACHE_BYTES);
if (!copy) { if (!copy) {
...@@ -377,9 +388,12 @@ static void __init setup_boot_config(void) ...@@ -377,9 +388,12 @@ static void __init setup_boot_config(void)
/* Also, "init." keys are init arguments */ /* Also, "init." keys are init arguments */
extra_init_args = xbc_make_cmdline("init"); extra_init_args = xbc_make_cmdline("init");
} }
return;
not_found:
pr_err("'bootconfig' found on command line, but no bootconfig found\n");
} }
#else #else
#define setup_boot_config() do { } while (0) #define setup_boot_config(cmdline) do { } while (0)
#endif #endif
/* Change NUL term back to "=", to make "param" the whole string. */ /* Change NUL term back to "=", to make "param" the whole string. */
...@@ -760,7 +774,7 @@ asmlinkage __visible void __init start_kernel(void) ...@@ -760,7 +774,7 @@ asmlinkage __visible void __init start_kernel(void)
pr_notice("%s", linux_banner); pr_notice("%s", linux_banner);
early_security_init(); early_security_init();
setup_arch(&command_line); setup_arch(&command_line);
setup_boot_config(); setup_boot_config(command_line);
setup_command_line(command_line); setup_command_line(command_line);
setup_nr_cpu_ids(); setup_nr_cpu_ids();
setup_per_cpu_areas(); setup_per_cpu_areas();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment