summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Buren <braewoods+rb@braewoods.net>2020-10-30 00:19:37 +0000
committerWilliam Wilgus <me.theuser@yahoo.com>2020-10-30 05:20:42 +0000
commit6bc6af6a0ec5ff6a69091d9c46c1a890a1e706a6 (patch)
tree7ca9e9a0743f57017dc137e7ad61362f0a248fed
parent07fcced4fb27050d02c2e9b4171b6e0ee032642d (diff)
downloadrockbox-6bc6af6a0ec5ff6a69091d9c46c1a890a1e706a6.tar.gz
rockbox-6bc6af6a0ec5ff6a69091d9c46c1a890a1e706a6.tar.bz2
rockbox-6bc6af6a0ec5ff6a69091d9c46c1a890a1e706a6.zip
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
-rw-r--r--apps/plugins/iriver_flash.c61
1 files changed, 46 insertions, 15 deletions
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;
}