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
This commit is contained in:
James Buren 2020-10-30 00:19:37 +00:00 committed by William Wilgus
parent 07fcced4fb
commit 6bc6af6a0e

View file

@ -31,7 +31,7 @@
/* All CFI flash routines are copied and ported from firmware_flash.c */ /* All CFI flash routines are copied and ported from firmware_flash.c */
unsigned char *audiobuf; uint8_t* audiobuf;
ssize_t audiobuf_size; ssize_t audiobuf_size;
#if !defined(IRIVER_H100_SERIES) && !defined(IRIVER_H300_SERIES) #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 */ static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */
#endif #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 */ /* read the manufacturer and device ID */
static void cfi_read_id(struct flash_info* pInfo) static void cfi_read_id(struct flash_info* pInfo)
{ {
@ -230,11 +238,12 @@ bool confirm(const char *msg)
return ret; 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 fd;
int len, rc; off_t len;
int i; uint32_t checksum;
char model[4];
uint32_t sum; uint32_t sum;
fd = rb->open(filename, O_RDONLY); fd = rb->open(filename, O_RDONLY);
@ -242,7 +251,6 @@ int load_firmware_file(const char *filename, uint32_t *checksum)
return -1; return -1;
len = rb->filesize(fd); len = rb->filesize(fd);
if (audiobuf_size < len) if (audiobuf_size < len)
{ {
rb->splash(HZ*3, "Aborting: Out of memory!"); rb->splash(HZ*3, "Aborting: Out of memory!");
@ -250,29 +258,52 @@ int load_firmware_file(const char *filename, uint32_t *checksum)
return -2; return -2;
} }
rb->read(fd, checksum, 4); if (rb->read(fd, &checksum, sizeof(checksum)) != sizeof(checksum))
rb->lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
len -= FIRMWARE_OFFSET_FILE_DATA;
rc = rb->read(fd, audiobuf, len);
rb->close(fd);
if (rc != len)
{ {
rb->splash(HZ*3, "Aborting: Read failure"); rb->splash(HZ*3, "Aborting: Read failure");
rb->close(fd);
return -3; return -3;
} }
/* Verify the checksum */ if (rb->read(fd, model, sizeof(model)) != sizeof(model))
sum = MODEL_NUMBER;
for (i = 0; i < len; i++)
sum += audiobuf[i];
if (sum != *checksum)
{ {
rb->splash(HZ*3, "Aborting: Checksums mismatch!"); rb->splash(HZ*3, "Aborting: Read failure");
rb->close(fd);
return -4; return -4;
} }
len -= FIRMWARE_OFFSET_FILE_DATA;
if (rb->read(fd, audiobuf, len) != len)
{
rb->splash(HZ*3, "Aborting: Read failure");
rb->close(fd);
return -5;
}
rb->close(fd);
/* Verify the checksum */
sum = MODEL_NUMBER;
for (off_t i = 0; i < len; i++)
sum += audiobuf[i];
if (sum != checksum)
{
rb->splash(HZ*3, "Aborting: Checksums mismatch!");
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; return len;
} }