Commit 85c46b78 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Steven Rostedt (VMware)
Browse files

bootconfig: Add bootconfig magic word for indicating bootconfig explicitly

Add bootconfig magic word to the end of bootconfig on initrd
image for indicating explicitly the bootconfig is there.
Also tools/bootconfig treats wrong size or wrong checksum or
parse error as an error, because if there is a bootconfig magic
word, there must be a bootconfig.

The bootconfig magic word is "#BOOTCONFIG\n", 12 bytes word.
Thus the block image of the initrd file with bootconfig is
as follows.

[Initrd][bootconfig][size][csum][#BOOTCONFIG\n]

Link: http://lkml.kernel.org/r/158220112263.26565.3944814205960612841.stgit@devnote2



Suggested-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent d8a953dd
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -102,9 +102,13 @@ Boot Kernel With a Boot Config
==============================

Since the boot configuration file is loaded with initrd, it will be added
to the end of the initrd (initramfs) image file. The Linux kernel decodes
the last part of the initrd image in memory to get the boot configuration
data.
to the end of the initrd (initramfs) image file with size, checksum and
12-byte magic word as below.

[initrd][bootconfig][size(u32)][checksum(u32)][#BOOTCONFIG\n]

The Linux kernel decodes the last part of the initrd image in memory to
get the boot configuration data.
Because of this "piggyback" method, there is no need to change or
update the boot loader and the kernel image itself.

+3 −0
Original line number Diff line number Diff line
@@ -10,6 +10,9 @@
#include <linux/kernel.h>
#include <linux/types.h>

#define BOOTCONFIG_MAGIC	"#BOOTCONFIG\n"
#define BOOTCONFIG_MAGIC_LEN	12

/* XBC tree node */
struct xbc_node {
	u16 next;
+1 −1
Original line number Diff line number Diff line
@@ -1222,7 +1222,7 @@ config BOOT_CONFIG
	  Extra boot config allows system admin to pass a config file as
	  complemental extension of kernel cmdline when booting.
	  The boot config file must be attached at the end of initramfs
	  with checksum and size.
	  with checksum, size and magic word.
	  See <file:Documentation/admin-guide/bootconfig.rst> for details.

	  If unsure, say Y.
+5 −1
Original line number Diff line number Diff line
@@ -374,7 +374,11 @@ static void __init setup_boot_config(const char *cmdline)
	if (!initrd_end)
		goto not_found;

	hdr = (u32 *)(initrd_end - 8);
	data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
	if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
		goto not_found;

	hdr = (u32 *)(data - 8);
	size = hdr[0];
	csum = hdr[1];

+32 −11
Original line number Diff line number Diff line
@@ -131,15 +131,26 @@ int load_xbc_from_initrd(int fd, char **buf)
	struct stat stat;
	int ret;
	u32 size = 0, csum = 0, rcsum;
	char magic[BOOTCONFIG_MAGIC_LEN];

	ret = fstat(fd, &stat);
	if (ret < 0)
		return -errno;

	if (stat.st_size < 8)
	if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
		return 0;

	if (lseek(fd, -8, SEEK_END) < 0) {
	if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0) {
		pr_err("Failed to lseek: %d\n", -errno);
		return -errno;
	}
	if (read(fd, magic, BOOTCONFIG_MAGIC_LEN) < 0)
		return -errno;
	/* Check the bootconfig magic bytes */
	if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
		return 0;

	if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0) {
		pr_err("Failed to lseek: %d\n", -errno);
		return -errno;
	}
@@ -150,11 +161,14 @@ int load_xbc_from_initrd(int fd, char **buf)
	if (read(fd, &csum, sizeof(u32)) < 0)
		return -errno;

	/* Wrong size, maybe no boot config here */
	if (stat.st_size < size + 8)
		return 0;
	/* Wrong size error  */
	if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
		pr_err("bootconfig size is too big\n");
		return -E2BIG;
	}

	if (lseek(fd, stat.st_size - 8 - size, SEEK_SET) < 0) {
	if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
		  SEEK_SET) < 0) {
		pr_err("Failed to lseek: %d\n", -errno);
		return -errno;
	}
@@ -163,17 +177,17 @@ int load_xbc_from_initrd(int fd, char **buf)
	if (ret < 0)
		return ret;

	/* Wrong Checksum, maybe no boot config here */
	/* Wrong Checksum */
	rcsum = checksum((unsigned char *)*buf, size);
	if (csum != rcsum) {
		pr_err("checksum error: %d != %d\n", csum, rcsum);
		return 0;
		return -EINVAL;
	}

	ret = xbc_init(*buf);
	/* Wrong data, maybe no boot config here */
	/* Wrong data */
	if (ret < 0)
		return 0;
		return ret;

	return size;
}
@@ -226,7 +240,8 @@ int delete_xbc(const char *path)
	} else if (size > 0) {
		ret = fstat(fd, &stat);
		if (!ret)
			ret = ftruncate(fd, stat.st_size - size - 8);
			ret = ftruncate(fd, stat.st_size
					- size - 8 - BOOTCONFIG_MAGIC_LEN);
		if (ret)
			ret = -errno;
	} /* Ignore if there is no boot config in initrd */
@@ -295,6 +310,12 @@ int apply_xbc(const char *path, const char *xbc_path)
		pr_err("Failed to apply a boot config: %d\n", ret);
		return ret;
	}
	/* Write a magic word of the bootconfig */
	ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
	if (ret < 0) {
		pr_err("Failed to apply a boot config magic: %d\n", ret);
		return ret;
	}
	close(fd);
	free(data);

Loading