diff options
author | Uwe Kleine-König <uwe@kleine-koenig.org> | 2016-01-22 20:33:40 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-01-26 08:00:15 +0100 |
commit | 39ebd7e73bec3a96f1563dcb89793b1dff187b13 (patch) | |
tree | 7b63c8a38b5a376fcdebcf3bb71e85d7579683fd /scripts/kwboot.c | |
parent | a03a3915d9e76372dd24a6f3c01eb3b5efb940ac (diff) | |
download | barebox-39ebd7e73bec3a96f1563dcb89793b1dff187b13.tar.gz barebox-39ebd7e73bec3a96f1563dcb89793b1dff187b13.tar.xz |
kwboot: do a filetype check before sending the image
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts/kwboot.c')
-rw-r--r-- | scripts/kwboot.c | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/scripts/kwboot.c b/scripts/kwboot.c index 46328d8ed0..9b0d1d0602 100644 --- a/scripts/kwboot.c +++ b/scripts/kwboot.c @@ -546,6 +546,63 @@ out: return rc; } +static int +kwboot_check_image(const unsigned char *img, size_t size) +{ + size_t i; + size_t header_size, image_size; + unsigned char csum = 0; + + if (size < 0x20) { + fprintf(stderr, + "Image too small to even contain a Main Header\n"); + return 1; + } + + switch (img[0x0]) { + case 0x5a: /* SPI/NOR */ + case 0x69: /* UART0 */ + case 0x78: /* SATA */ + case 0x8b: /* NAND */ + case 0x9c: /* PCIe */ + break; + default: + fprintf(stderr, + "Unknown boot source: 0x%hhx\n", img[0x0]); + return 1; + } + + if (img[0x8] != 1) { + fprintf(stderr, "Unknown version: 0x%hhx\n", img[0x8]); + return 1; + } + + image_size = img[0x4] | (img[0x5] << 8) | + (img[0x6] << 16) | (img[0x7] << 24); + + header_size = (img[0x9] << 16) | img[0xa] | (img[0xb] << 8); + + if (header_size + image_size != size) { + fprintf(stderr, "Size mismatch (%zu + %zu != %zu)\n", + header_size, image_size, size); + return 1; + } + + for (i = 0; i < header_size; ++i) + csum += img[i]; + + csum -= img[0x1f]; + + if (csum != img[0x1f]) { + fprintf(stderr, + "Checksum mismatch: specified: 0x%02hhx, calculated: 0x%02hhx\n", + img[0x1f], csum); + return 1; + } + + return 0; +} + static void * kwboot_mmap_image(const char *path, size_t *size, int prot) { @@ -608,7 +665,7 @@ int main(int argc, char **argv) { const char *ttypath, *imgpath; - int rv, rc, tty, term; + int rv, rc, tty, term, force = 0; void *bootmsg; void *debugmsg; void *img; @@ -628,7 +685,7 @@ main(int argc, char **argv) kwboot_verbose = isatty(STDOUT_FILENO); do { - int c = getopt(argc, argv, "hb:dtB:D:"); + int c = getopt(argc, argv, "b:dfhtB:D:"); if (c < 0) break; @@ -651,6 +708,10 @@ main(int argc, char **argv) term = 1; break; + case 'f': + force = 1; + break; + case 'B': speed = kwboot_tty_speed(atoi(optarg)); if (speed == -1) @@ -684,6 +745,13 @@ main(int argc, char **argv) perror(imgpath); goto out; } + + rc = kwboot_check_image(img, size); + if (rc && !force) { + fprintf(stderr, + "Image check failed, restart with -f to ignore\n"); + goto out; + } } if (debugmsg) { |