From: Borislav Petkov <bp@xxxxxxx>
Date: Tue, 15 Nov 2022 19:30:09 +0100
Use cmdline_prepare() in the compressed stage so that builtin
command line (CONFIG_CMDLINE_BOOL) and overridden command line
(CONFIG_CMDLINE_OVERRIDE) strings are visible in the compressed kernel
too.
Use case being, supplying earlyprintk via a compile-time option for
booting on systems with broken UEFI command line arguments via EFISTUB.
Reported-by: Evgeniy Baskov <baskov@xxxxxxxxx>
Signed-off-by: Borislav Petkov <bp@xxxxxxx>
---
arch/x86/boot/compressed/misc.c | 7 +++++++
arch/x86/include/asm/shared/cmdline.h | 20 ++++++++++++++++----
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index cf690d8712f4..b1077b2fdba6 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -18,6 +18,9 @@
#include "../string.h"
#include "../voffset.h"
#include <asm/bootparam_utils.h>
+#include <asm/shared/cmdline.h>
+
+extern unsigned long get_cmd_line_ptr(void);
/*
* WARNING!!
@@ -355,6 +358,7 @@ asmlinkage __visible void *extract_kernel(void
*rmode, memptr heap,
{
const unsigned long kernel_total_size = VO__end - VO__text;
unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
+ char *cmdline = (char *)get_cmd_line_ptr();
unsigned long needed_size;
/* Retain x86 boot parameters pointer passed from startup_32/64. */
@@ -365,6 +369,9 @@ asmlinkage __visible void *extract_kernel(void
*rmode, memptr heap,
sanitize_boot_params(boot_params);
+ /* Destination and boot command line are the same */
+ cmdline_prepare(cmdline, BUILTIN_CMDLINE, cmdline);
+
if (boot_params->screen_info.orig_video_mode == 7) {
vidmem = (char *) 0xb0000;
vidport = 0x3b4;
diff --git a/arch/x86/include/asm/shared/cmdline.h
b/arch/x86/include/asm/shared/cmdline.h
index e09c06338567..8a7d8f579575 100644
--- a/arch/x86/include/asm/shared/cmdline.h
+++ b/arch/x86/include/asm/shared/cmdline.h
@@ -8,6 +8,15 @@
#define BUILTIN_CMDLINE ""
#endif
+#define _SETUP
+#include <asm/setup.h> /* For COMMAND_LINE_SIZE */
+#undef _SETUP
+
+/*
+ * Add @boot_command_line to @dst only if it is not in @dst already.
The compressed kernel
+ * has the command line pointer in setup_header.cmd_line_ptr which is
set by the boot
+ * loader so @boot_command_line == @dst there, see the call in
compressed/misc.c
+ */
static inline void cmdline_prepare(char *dst,
const char *builtin_cmdline,
char *boot_command_line)
@@ -20,15 +29,18 @@ static inline void cmdline_prepare(char *dst,
/* Add builtin cmdline */
strlcat(dst, builtin_cmdline, COMMAND_LINE_SIZE);
strlcat(dst, " ", COMMAND_LINE_SIZE);
- /* Add boot cmdline */
- strlcat(dst, boot_command_line, COMMAND_LINE_SIZE);
+
+ if (dst != boot_command_line)
+ strlcat(dst, boot_command_line, COMMAND_LINE_SIZE);
}
} else {
- strscpy(dst, boot_command_line, COMMAND_LINE_SIZE);
+ if (dst != boot_command_line)
+ strscpy(dst, boot_command_line, COMMAND_LINE_SIZE);
}
/* Copy back into boot command line, see setup_command_line() */
- strscpy(boot_command_line, dst, COMMAND_LINE_SIZE);
+ if (dst != boot_command_line)
+ strscpy(boot_command_line, dst, COMMAND_LINE_SIZE);
}
#endif /* _ASM_X86_SHARED_CMDLINE_H */
--
2.35.1