diff options
author | Vikram Pandita <vikram.pandita@ti.com> | 2011-02-28 15:15:37 -0800 |
---|---|---|
committer | Vikram Pandita <vikram.pandita@ti.com> | 2011-02-28 15:35:35 -0800 |
commit | 5824bf5fb9037e96d98d53dad1ab18c9696e9038 (patch) | |
tree | 00227a005c27b908cdd52200d696fd832d1e815b | |
parent | c98271da07cd3ba7bbc62086edc4928c8330686f (diff) | |
download | u-boot-pandroid-5824bf5fb9037e96d98d53dad1ab18c9696e9038.tar.gz |
fastboot: sparse: fix section size exceed
GPT partition size is fixed.
While un-sparsing, the uncompressed image can exceed the partition size.
Make the sparse write safe against partition size exceeds.
Fix:
early size check failure as reported by:
Brian Swetland <swetland@google.com>
Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
-rw-r--r-- | common/cmd_fastboot.c | 1 | ||||
-rw-r--r-- | cpu/omap4/sparse.c | 23 | ||||
-rw-r--r-- | include/sparse.h | 1 |
3 files changed, 21 insertions, 4 deletions
diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c index b5f0145d..5296739a 100644 --- a/common/cmd_fastboot.c +++ b/common/cmd_fastboot.c @@ -1318,6 +1318,7 @@ static int rx_handler (const unsigned char *buffer, unsigned int buffer_size) printf("fastboot: %s is in sparse format\n", ptn->name); if (!do_unsparse(interface.transfer_buffer, ptn->start, + ptn->length, slot_no)) { printf("Writing sparsed: '%s' DONE!\n", ptn->name); } else { diff --git a/cpu/omap4/sparse.c b/cpu/omap4/sparse.c index e45de2c9..ae108f2f 100644 --- a/cpu/omap4/sparse.c +++ b/cpu/omap4/sparse.c @@ -49,7 +49,8 @@ int mmc_compare(unsigned mmcc, unsigned char *src, unsigned sector, unsigned len } -int _unsparse(unsigned char *source, u32 sector, unsigned mmcc, +int _unsparse(unsigned char *source, u32 sector, u32 section_size, + unsigned mmcc, int (*WRITE)(unsigned mwcc, unsigned char *src, unsigned sector, unsigned len)) { @@ -58,6 +59,12 @@ int _unsparse(unsigned char *source, u32 sector, unsigned mmcc, printf("sparse: write to mmc slot[%d] @ %d\n", mmcc, sector); + if ((header->total_blks * header->blk_sz) > section_size) { + printf("sparse: section size %d MB limit: exceeded\n", + section_size/(1024*1024)); + return 1; + } + if (header->magic != SPARSE_HEADER_MAGIC) { printf("sparse: bad magic\n"); return 1; @@ -92,6 +99,10 @@ int _unsparse(unsigned char *source, u32 sector, unsigned mmcc, } outlen += len; + if (outlen > section_size) { + printf("sparse: section size %d MB limit: exceeded\n", section_size/(1024*1024)); + return 1; + } #ifdef DEBUG printf("sparse: RAW blk=%d bsz=%d: write(sector=%d,len=%d)\n", chunk->chunk_sz, header->blk_sz, sector, len); @@ -118,6 +129,10 @@ int _unsparse(unsigned char *source, u32 sector, unsigned mmcc, #endif outlen += len; + if (outlen > section_size) { + printf("sparse: section size %d MB limit: exceeded\n", section_size/(1024*1024)); + return 1; + } sector += (len / 512); break; @@ -131,13 +146,13 @@ int _unsparse(unsigned char *source, u32 sector, unsigned mmcc, return 0; } -u8 do_unsparse(unsigned char *source, u32 sector, char *slot_no) +u8 do_unsparse(unsigned char *source, u32 sector, u32 section_size, char *slot_no) { unsigned mmcc = simple_strtoul(slot_no, NULL, 16); - if (_unsparse(source, sector, mmcc, mmc_write)) + if (_unsparse(source, sector, section_size, mmcc, mmc_write)) return 1; #if DEBUG - if (_unsparse(source, sector, mmcc, mmc_compare)) + if (_unsparse(source, sector, section_size, mmcc, mmc_compare)) return 1; #endif return 0; diff --git a/include/sparse.h b/include/sparse.h index 7c8e6593..77b93ec5 100644 --- a/include/sparse.h +++ b/include/sparse.h @@ -32,5 +32,6 @@ u8 do_unsparse(unsigned char *source, u32 sector, + u32 section_size, char *slot_no); #endif /* __SPARSE_H */ |