summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chromeos/gbb.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/lib/chromeos/gbb.c b/lib/chromeos/gbb.c
index 25d5741318..77e524b2c1 100644
--- a/lib/chromeos/gbb.c
+++ b/lib/chromeos/gbb.c
@@ -16,16 +16,39 @@
#define PREFIX "gbb: "
-int gbb_init(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset)
+int gbb_init(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset,
+ size_t gbb_size)
{
#ifndef CONFIG_HARDWARE_MAPPED_SPI
GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)gbb;
+ uint32_t hwid_end;
+ uint32_t rootkey_end;
if (file->read(file, gbb_offset, sizeof(*gbbh), gbbh)) {
VBDEBUG(PREFIX "failed to read GBB header\n");
return 1;
}
+ hwid_end = gbbh->hwid_offset + gbbh->hwid_size;
+ rootkey_end = gbbh->rootkey_offset + gbbh->rootkey_size;
+ if (hwid_end < gbbh->hwid_offset || hwid_end > gbb_size ||
+ rootkey_end < gbbh->rootkey_offset ||
+ rootkey_end > gbb_size) {
+ VBDEBUG(PREFIX "%s: invalid gbb header entries\n", __func__);
+ VBDEBUG(PREFIX " hwid_end=%x\n", hwid_end);
+ VBDEBUG(PREFIX " gbbh->hwid_offset=%x\n", gbbh->hwid_offset);
+ VBDEBUG(PREFIX " gbb_size=%x\n", gbb_size);
+ VBDEBUG(PREFIX " rootkey_end=%x\n", rootkey_end);
+ VBDEBUG(PREFIX " gbbh->rootkey_offset=%x\n",
+ gbbh->rootkey_offset);
+ VBDEBUG(PREFIX " %d, %d, %d, %d\n",
+ hwid_end < gbbh->hwid_offset,
+ hwid_end >= gbb_size,
+ rootkey_end < gbbh->rootkey_offset,
+ rootkey_end >= gbb_size);
+ return 1;
+ }
+
if (file->read(file, gbb_offset + gbbh->hwid_offset,
gbbh->hwid_size,
gbb + gbbh->hwid_offset)) {
@@ -40,6 +63,7 @@ int gbb_init(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset)
return 1;
}
#else
+ /* No data is actually moved in this case so no bounds checks. */
if (file->read(file, gbb_offset,
sizeof(GoogleBinaryBlockHeader), gbb)) {
VBDEBUG(PREFIX "failed to read GBB header\n");
@@ -51,9 +75,16 @@ int gbb_init(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset)
}
#ifndef CONFIG_HARDWARE_MAPPED_SPI
-int gbb_read_bmp_block(void *gbb, firmware_storage_t *file, uint32_t gbb_offset)
+int gbb_read_bmp_block(void *gbb, firmware_storage_t *file, uint32_t gbb_offset,
+ size_t gbb_size)
{
GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)gbb;
+ uint32_t bmpfv_end = gbbh->bmpfv_offset + gbbh->bmpfv_size;
+
+ if (bmpfv_end < gbbh->bmpfv_offset || bmpfv_end > gbb_size) {
+ VBDEBUG(PREFIX "%s: invalid gbb header entries\n", __func__);
+ return 1;
+ }
if (file->read(file, gbb_offset + gbbh->bmpfv_offset,
gbbh->bmpfv_size,
@@ -65,10 +96,23 @@ int gbb_read_bmp_block(void *gbb, firmware_storage_t *file, uint32_t gbb_offset)
return 0;
}
-int gbb_read_recovery_key(void *gbb,
- firmware_storage_t *file, uint32_t gbb_offset)
+int gbb_read_recovery_key(void *gbb, firmware_storage_t *file,
+ uint32_t gbb_offset, size_t gbb_size)
{
GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)gbb;
+ uint32_t rkey_end = gbbh->recovery_key_offset +
+ gbbh->recovery_key_size;
+
+ if (rkey_end < gbbh->recovery_key_offset || rkey_end > gbb_size) {
+ VBDEBUG(PREFIX "%s: invalid gbb header entries\n", __func__);
+ VBDEBUG(PREFIX " gbbh->recovery_key_offset=%x\n",
+ gbbh->recovery_key_offset);
+ VBDEBUG(PREFIX " gbbh->recovery_key_size=%x\n",
+ gbbh->recovery_key_size);
+ VBDEBUG(PREFIX " rkey_end=%x\n", rkey_end);
+ VBDEBUG(PREFIX " gbb_size=%x\n", gbb_size);
+ return 1;
+ }
if (file->read(file, gbb_offset + gbbh->recovery_key_offset,
gbbh->recovery_key_size,