From 6bc6af6a0ec5ff6a69091d9c46c1a890a1e706a6 Mon Sep 17 00:00:00 2001 From: James Buren Date: Fri, 30 Oct 2020 00:19:37 +0000 Subject: iriver_flash: revise load_firmware_file function This moves the checksum into the local stack and turns the second parameter into an optional argument. This also reads the model segment that was previously unused so it can also be checked as an extra safeguard in the event the checksum somehow matches yet the model is incorrect. Change-Id: I9a8c2d731e4f1818e6e4aee3c3978777c16ccf19 --- apps/plugins/iriver_flash.c | 61 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'apps/plugins') diff --git a/apps/plugins/iriver_flash.c b/apps/plugins/iriver_flash.c index e33e422d01..449bf349a8 100644 --- a/apps/plugins/iriver_flash.c +++ b/apps/plugins/iriver_flash.c @@ -31,7 +31,7 @@ /* All CFI flash routines are copied and ported from firmware_flash.c */ -unsigned char *audiobuf; +uint8_t* audiobuf; ssize_t audiobuf_size; #if !defined(IRIVER_H100_SERIES) && !defined(IRIVER_H300_SERIES) @@ -66,6 +66,14 @@ enum sections { static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */ #endif +#ifdef IRIVER_H100 +#define MODEL "h100" +#elif defined(IRIVER_H120) +#define MODEL "h120" +#elif defined(IRIVER_H300) +#define MODEL "h300" +#endif + /* read the manufacturer and device ID */ static void cfi_read_id(struct flash_info* pInfo) { @@ -230,19 +238,19 @@ bool confirm(const char *msg) return ret; } -int load_firmware_file(const char *filename, uint32_t *checksum) +static off_t load_firmware_file(const char* filename, uint32_t* out_checksum) { int fd; - int len, rc; - int i; + off_t len; + uint32_t checksum; + char model[4]; uint32_t sum; - fd = rb->open(filename, O_RDONLY); + fd = rb->open(filename, O_RDONLY); if (fd < 0) return -1; len = rb->filesize(fd); - if (audiobuf_size < len) { rb->splash(HZ*3, "Aborting: Out of memory!"); @@ -250,29 +258,52 @@ int load_firmware_file(const char *filename, uint32_t *checksum) return -2; } - rb->read(fd, checksum, 4); - rb->lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); + if (rb->read(fd, &checksum, sizeof(checksum)) != sizeof(checksum)) + { + rb->splash(HZ*3, "Aborting: Read failure"); + rb->close(fd); + return -3; + } + + if (rb->read(fd, model, sizeof(model)) != sizeof(model)) + { + rb->splash(HZ*3, "Aborting: Read failure"); + rb->close(fd); + return -4; + } + len -= FIRMWARE_OFFSET_FILE_DATA; - rc = rb->read(fd, audiobuf, len); - rb->close(fd); - if (rc != len) + if (rb->read(fd, audiobuf, len) != len) { rb->splash(HZ*3, "Aborting: Read failure"); - return -3; + rb->close(fd); + return -5; } + rb->close(fd); + /* Verify the checksum */ sum = MODEL_NUMBER; - for (i = 0; i < len; i++) + for (off_t i = 0; i < len; i++) sum += audiobuf[i]; - if (sum != *checksum) + if (sum != checksum) { rb->splash(HZ*3, "Aborting: Checksums mismatch!"); - return -4; + return -6; } + /* Verify the model */ + if (rb->memcmp(model, MODEL, sizeof(model)) != 0) + { + rb->splash(HZ*3, "Aborting: Models mismatch!"); + return -7; + } + + if (out_checksum != NULL) + *out_checksum = checksum; + return len; } -- cgit v1.2.3