aboutsummaryrefslogtreecommitdiff
path: root/squashfs-tools
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@squashfs.org.uk>2013-01-28 04:07:48 +0000
committerPhillip Lougher <phillip@squashfs.org.uk>2013-01-28 04:07:48 +0000
commit65d752a3b07cdff8d9718e7c9e9325c76a896468 (patch)
tree394885ba150da6cd1e1989ed7b09f6897cd2893f /squashfs-tools
parenta522d5f17c76d6c8a86d99366eff0e94921f6cb9 (diff)
downloadsquashfs-tools-65d752a3b07cdff8d9718e7c9e9325c76a896468.tar.gz
unsquash-3: harden fragment table reading against corrupted filesystems
Harden fragment table reading, checking against unexpected metadata block length, ensuring no buffer overflow/underflow occurs. Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Diffstat (limited to 'squashfs-tools')
-rw-r--r--squashfs-tools/unsquash-3.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/squashfs-tools/unsquash-3.c b/squashfs-tools/unsquash-3.c
index 726bcf2..0eda486 100644
--- a/squashfs-tools/unsquash-3.c
+++ b/squashfs-tools/unsquash-3.c
@@ -29,7 +29,9 @@ static squashfs_fragment_entry_3 *fragment_table;
int read_fragment_table_3()
{
- int res, i, indexes = SQUASHFS_FRAGMENT_INDEXES_3(sBlk.s.fragments);
+ int res, i;
+ int bytes = SQUASHFS_FRAGMENT_BYTES_3(sBlk.s.fragments);
+ int indexes = SQUASHFS_FRAGMENT_INDEXES_3(sBlk.s.fragments);
long long fragment_table_index[indexes];
TRACE("read_fragment_table: %d fragments, reading %d fragment indexes "
@@ -39,8 +41,7 @@ int read_fragment_table_3()
if(sBlk.s.fragments == 0)
return TRUE;
- fragment_table = malloc(sBlk.s.fragments *
- sizeof(squashfs_fragment_entry_3));
+ fragment_table = malloc(bytes);
if(fragment_table == NULL)
EXIT_UNSQUASH("read_fragment_table: failed to allocate "
"fragment table\n");
@@ -70,8 +71,10 @@ int read_fragment_table_3()
}
for(i = 0; i < indexes; i++) {
- int length = read_block(fd, fragment_table_index[i], NULL, 0,
- ((char *) fragment_table) + (i *
+ int expected = (i + 1) != indexes ? SQUASHFS_METADATA_SIZE :
+ bytes & (SQUASHFS_METADATA_SIZE - 1);
+ int length = read_block(fd, fragment_table_index[i], NULL,
+ expected, ((char *) fragment_table) + (i *
SQUASHFS_METADATA_SIZE));
TRACE("Read fragment table block %d, from 0x%llx, length %d\n",
i, fragment_table_index[i], length);