tools/bootconfig: Align the bootconfig applied initrd image size to 4
authorMasami Hiramatsu <mhiramat@kernel.org>
Thu, 19 Nov 2020 05:53:40 +0000 (14:53 +0900)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Thu, 19 Nov 2020 13:55:44 +0000 (08:55 -0500)
Align the bootconfig applied initrd image size to 4. To fill the gap,
the bootconfig command uses null characters in between the bootconfig
data and the footer. This will expands the footer size but don't change
the checksum.
Thus the block image of the initrd file with bootconfig is as follows.

[initrd][bootconfig][(pad)][size][csum]["#BOOTCONFIG\n"]

Link: https://lkml.kernel.org/r/160576522046.320071.8550680670010950634.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
include/linux/bootconfig.h
tools/bootconfig/main.c
tools/bootconfig/test-bootconfig.sh

index 9903088891fa8a81dbae5df628aaceb64b2a20eb..2696eb0fc14976a3420f89a9e63d4a585f017807 100644 (file)
@@ -12,6 +12,9 @@
 
 #define BOOTCONFIG_MAGIC       "#BOOTCONFIG\n"
 #define BOOTCONFIG_MAGIC_LEN   12
+#define BOOTCONFIG_ALIGN_SHIFT 2
+#define BOOTCONFIG_ALIGN       (1 << BOOTCONFIG_ALIGN_SHIFT)
+#define BOOTCONFIG_ALIGN_MASK  (BOOTCONFIG_ALIGN - 1)
 
 /* XBC tree node */
 struct xbc_node {
index a0733cbb3c49fadb9f14bbcaf3a70940fc23c085..4a445b6304bb724210216c899b2f94ffbf2033cd 100644 (file)
@@ -337,12 +337,13 @@ static int delete_xbc(const char *path)
 
 static int apply_xbc(const char *path, const char *xbc_path)
 {
+       char *buf, *data, *p;
+       size_t total_size;
        struct stat stat;
+       const char *msg;
        u32 size, csum;
-       char *buf, *data;
+       int pos, pad;
        int ret, fd;
-       const char *msg;
-       int pos;
 
        ret = load_xbc_file(xbc_path, &buf);
        if (ret < 0) {
@@ -352,13 +353,12 @@ static int apply_xbc(const char *path, const char *xbc_path)
        size = strlen(buf) + 1;
        csum = checksum((unsigned char *)buf, size);
 
-       /* Prepare xbc_path data */
-       data = malloc(size + 8);
+       /* Backup the bootconfig data */
+       data = calloc(size + BOOTCONFIG_ALIGN +
+                     sizeof(u32) + sizeof(u32) + BOOTCONFIG_MAGIC_LEN, 1);
        if (!data)
                return -ENOMEM;
-       strcpy(data, buf);
-       *(u32 *)(data + size) = size;
-       *(u32 *)(data + size + 4) = csum;
+       memcpy(data, buf, size);
 
        /* Check the data format */
        ret = xbc_init(buf, &msg, &pos);
@@ -399,24 +399,35 @@ static int apply_xbc(const char *path, const char *xbc_path)
                pr_err("Failed to get the size of %s\n", path);
                goto out;
        }
-       ret = write(fd, data, size + 8);
-       if (ret < size + 8) {
+
+       /* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
+       total_size = stat.st_size + size + sizeof(u32) * 2 + BOOTCONFIG_MAGIC_LEN;
+       pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
+       size += pad;
+
+       /* Add a footer */
+       p = data + size;
+       *(u32 *)p = size;
+       p += sizeof(u32);
+
+       *(u32 *)p = csum;
+       p += sizeof(u32);
+
+       memcpy(p, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
+       p += BOOTCONFIG_MAGIC_LEN;
+
+       total_size = p - data;
+
+       ret = write(fd, data, total_size);
+       if (ret < total_size) {
                if (ret < 0)
                        ret = -errno;
                pr_err("Failed to apply a boot config: %d\n", ret);
-               if (ret < 0)
-                       goto out;
-               goto out_rollback;
-       }
-       /* Write a magic word of the bootconfig */
-       ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
-       if (ret < BOOTCONFIG_MAGIC_LEN) {
-               if (ret < 0)
-                       ret = -errno;
-               pr_err("Failed to apply a boot config magic: %d\n", ret);
-               goto out_rollback;
-       }
-       ret = 0;
+               if (ret >= 0)
+                       goto out_rollback;
+       } else
+               ret = 0;
+
 out:
        close(fd);
        free(data);
index d295e406a756ede11baae579189deca328636174..baed891d0ba4969a9b13fbe335898fee8661a0c1 100755 (executable)
@@ -9,6 +9,7 @@ else
   TESTDIR=.
 fi
 BOOTCONF=${TESTDIR}/bootconfig
+ALIGN=4
 
 INITRD=`mktemp ${TESTDIR}/initrd-XXXX`
 TEMPCONF=`mktemp ${TESTDIR}/temp-XXXX.bconf`
@@ -59,7 +60,10 @@ echo "Show command test"
 xpass $BOOTCONF $INITRD
 
 echo "File size check"
-xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9 + 12)
+total_size=$(expr $bconf_size + $initrd_size + 9 + 12 + $ALIGN - 1 )
+total_size=$(expr $total_size / $ALIGN)
+total_size=$(expr $total_size \* $ALIGN)
+xpass test $new_size -eq $total_size
 
 echo "Apply command repeat test"
 xpass $BOOTCONF -a $TEMPCONF $INITRD