diff options
author | Phillip Lougher <phillip@squashfs.org.uk> | 2013-01-28 04:07:48 +0000 |
---|---|---|
committer | Phillip Lougher <phillip@squashfs.org.uk> | 2013-01-28 04:07:48 +0000 |
commit | 65d752a3b07cdff8d9718e7c9e9325c76a896468 (patch) | |
tree | 394885ba150da6cd1e1989ed7b09f6897cd2893f /squashfs-tools | |
parent | a522d5f17c76d6c8a86d99366eff0e94921f6cb9 (diff) | |
download | squashfs-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.c | 13 |
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); |