Skip to content

Commit de462e5

Browse files
mhiramatrostedt
authored andcommitted
bootconfig: Fix to remove bootconfig data from initrd while boot
If there is a bootconfig data in the tail of initrd/initramfs, initrd image sanity check caused an error while decompression stage as follows. [ 0.883882] Unpacking initramfs... [ 2.696429] Initramfs unpacking failed: invalid magic at start of compressed archive This error will be ignored if CONFIG_BLK_DEV_RAM=n, but CONFIG_BLK_DEV_RAM=y the kernel failed to mount rootfs and causes a panic. To fix this issue, shrink down the initrd_end for removing tailing bootconfig data while boot the kernel. Link: http://lkml.kernel.org/r/158788401014.24243.17424755854115077915.stgit@devnote2 Cc: Borislav Petkov <[email protected]> Cc: Kees Cook <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Andrew Morton <[email protected]> Cc: [email protected] Fixes: 7684b85 ("bootconfig: Load boot config from the tail of initrd") Signed-off-by: Masami Hiramatsu <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 6a8b55e commit de462e5

File tree

1 file changed

+52
-17
lines changed

1 file changed

+52
-17
lines changed

init/main.c

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,47 @@ static int __init loglevel(char *str)
257257

258258
early_param("loglevel", loglevel);
259259

260+
#ifdef CONFIG_BLK_DEV_INITRD
261+
static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
262+
{
263+
u32 size, csum;
264+
char *data;
265+
u32 *hdr;
266+
267+
if (!initrd_end)
268+
return NULL;
269+
270+
data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
271+
if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
272+
return NULL;
273+
274+
hdr = (u32 *)(data - 8);
275+
size = hdr[0];
276+
csum = hdr[1];
277+
278+
data = ((void *)hdr) - size;
279+
if ((unsigned long)data < initrd_start) {
280+
pr_err("bootconfig size %d is greater than initrd size %ld\n",
281+
size, initrd_end - initrd_start);
282+
return NULL;
283+
}
284+
285+
/* Remove bootconfig from initramfs/initrd */
286+
initrd_end = (unsigned long)data;
287+
if (_size)
288+
*_size = size;
289+
if (_csum)
290+
*_csum = csum;
291+
292+
return data;
293+
}
294+
#else
295+
static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
296+
{
297+
return NULL;
298+
}
299+
#endif
300+
260301
#ifdef CONFIG_BOOT_CONFIG
261302

262303
char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
@@ -357,37 +398,25 @@ static void __init setup_boot_config(const char *cmdline)
357398
int pos;
358399
u32 size, csum;
359400
char *data, *copy;
360-
u32 *hdr;
361401
int ret;
362402

403+
data = get_boot_config_from_initrd(&size, &csum);
404+
if (!data)
405+
goto not_found;
406+
363407
strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
364408
parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
365409
bootconfig_params);
366410

367411
if (!bootconfig_found)
368412
return;
369413

370-
if (!initrd_end)
371-
goto not_found;
372-
373-
data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
374-
if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
375-
goto not_found;
376-
377-
hdr = (u32 *)(data - 8);
378-
size = hdr[0];
379-
csum = hdr[1];
380-
381414
if (size >= XBC_DATA_MAX) {
382415
pr_err("bootconfig size %d greater than max size %d\n",
383416
size, XBC_DATA_MAX);
384417
return;
385418
}
386419

387-
data = ((void *)hdr) - size;
388-
if ((unsigned long)data < initrd_start)
389-
goto not_found;
390-
391420
if (boot_config_checksum((unsigned char *)data, size) != csum) {
392421
pr_err("bootconfig checksum failed\n");
393422
return;
@@ -420,8 +449,14 @@ static void __init setup_boot_config(const char *cmdline)
420449
not_found:
421450
pr_err("'bootconfig' found on command line, but no bootconfig found\n");
422451
}
452+
423453
#else
424-
#define setup_boot_config(cmdline) do { } while (0)
454+
455+
static void __init setup_boot_config(const char *cmdline)
456+
{
457+
/* Remove bootconfig data from initrd */
458+
get_boot_config_from_initrd(NULL, NULL);
459+
}
425460

426461
static int __init warn_bootconfig(char *str)
427462
{

0 commit comments

Comments
 (0)