diff options
Diffstat (limited to 'tools/bootconfig/main.c')
-rw-r--r-- | tools/bootconfig/main.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c index 8a48cc2536f5..57c669d2aa90 100644 --- a/tools/bootconfig/main.c +++ b/tools/bootconfig/main.c @@ -11,11 +11,16 @@ #include <string.h> #include <errno.h> #include <endian.h> +#include <assert.h> #include <linux/bootconfig.h> #define pr_err(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) +/* Bootconfig footer is [size][csum][BOOTCONFIG_MAGIC]. */ +#define BOOTCONFIG_FOOTER_SIZE \ + (sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN) + static int xbc_show_value(struct xbc_node *node, bool semicolon) { const char *val, *eol; @@ -185,7 +190,7 @@ static int load_xbc_from_initrd(int fd, char **buf) if (ret < 0) return -errno; - if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN) + if (stat.st_size < BOOTCONFIG_FOOTER_SIZE) return 0; if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0) @@ -198,7 +203,7 @@ static int load_xbc_from_initrd(int fd, char **buf) if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0) return 0; - if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0) + if (lseek(fd, -BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0) return pr_errno("Failed to lseek for size", -errno); if (read(fd, &size, sizeof(uint32_t)) < 0) @@ -210,12 +215,12 @@ static int load_xbc_from_initrd(int fd, char **buf) csum = le32toh(csum); /* Wrong size error */ - if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) { + if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) { pr_err("bootconfig size is too big\n"); return -E2BIG; } - if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN), + if (lseek(fd, stat.st_size - (size + BOOTCONFIG_FOOTER_SIZE), SEEK_SET) < 0) return pr_errno("Failed to lseek", -errno); @@ -346,7 +351,7 @@ static int delete_xbc(const char *path) ret = fstat(fd, &stat); if (!ret) ret = ftruncate(fd, stat.st_size - - size - 8 - BOOTCONFIG_MAGIC_LEN); + - size - BOOTCONFIG_FOOTER_SIZE); if (ret) ret = -errno; } /* Ignore if there is no boot config in initrd */ @@ -359,7 +364,12 @@ static int delete_xbc(const char *path) static int apply_xbc(const char *path, const char *xbc_path) { - char *buf, *data, *p; + struct { + uint32_t size; + uint32_t csum; + char magic[BOOTCONFIG_MAGIC_LEN]; + } footer; + char *buf, *data; size_t total_size; struct stat stat; const char *msg; @@ -376,8 +386,7 @@ static int apply_xbc(const char *path, const char *xbc_path) csum = xbc_calc_checksum(buf, size); /* Backup the bootconfig data */ - data = calloc(size + BOOTCONFIG_ALIGN + - sizeof(uint32_t) + sizeof(uint32_t) + BOOTCONFIG_MAGIC_LEN, 1); + data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1); if (!data) return -ENOMEM; memcpy(data, buf, size); @@ -425,22 +434,18 @@ static int apply_xbc(const char *path, const char *xbc_path) } /* To align up the total size to BOOTCONFIG_ALIGN, get padding size */ - total_size = stat.st_size + size + sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN; + total_size = stat.st_size + size + BOOTCONFIG_FOOTER_SIZE; pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size; size += pad; /* Add a footer */ - p = data + size; - *(uint32_t *)p = htole32(size); - p += sizeof(uint32_t); - - *(uint32_t *)p = htole32(csum); - p += sizeof(uint32_t); - - memcpy(p, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN); - p += BOOTCONFIG_MAGIC_LEN; + footer.size = htole32(size); + footer.csum = htole32(csum); + memcpy(footer.magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN); + static_assert(sizeof(footer) == BOOTCONFIG_FOOTER_SIZE); + memcpy(data + size, &footer, BOOTCONFIG_FOOTER_SIZE); - total_size = p - data; + total_size = size + BOOTCONFIG_FOOTER_SIZE; ret = write(fd, data, total_size); if (ret < total_size) { |