Skip to content

Commit

Permalink
bootconfig: Add bootconfig magic word for indicating bootconfig expli…
Browse files Browse the repository at this point in the history
…citly

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: Steven Rostedt <[email protected]>
Signed-off-by: Masami Hiramatsu <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
  • Loading branch information
mhiramat authored and rostedt committed Feb 20, 2020
1 parent d8a953d commit 85c46b7
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 17 deletions.
10 changes: 7 additions & 3 deletions Documentation/admin-guide/bootconfig.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
3 changes: 3 additions & 0 deletions include/linux/bootconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 5 additions & 1 deletion init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
43 changes: 32 additions & 11 deletions tools/bootconfig/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion tools/bootconfig/test-bootconfig.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ xpass $BOOTCONF -a $TEMPCONF $INITRD
new_size=$(stat -c %s $INITRD)

echo "File size check"
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9)
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9 + 12)

echo "Apply command repeat test"
xpass $BOOTCONF -a $TEMPCONF $INITRD
Expand Down

0 comments on commit 85c46b7

Please sign in to comment.