aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVikram Pandita <vikram.pandita@ti.com>2011-02-28 15:15:37 -0800
committerVikram Pandita <vikram.pandita@ti.com>2011-02-28 15:35:35 -0800
commit5824bf5fb9037e96d98d53dad1ab18c9696e9038 (patch)
tree00227a005c27b908cdd52200d696fd832d1e815b
parentc98271da07cd3ba7bbc62086edc4928c8330686f (diff)
downloadu-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.c1
-rw-r--r--cpu/omap4/sparse.c23
-rw-r--r--include/sparse.h1
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 */