diff options
author | Eric Biggers <ebiggers@google.com> | 2023-03-23 00:44:22 +0000 |
---|---|---|
committer | Eric Biggers <ebiggers@google.com> | 2023-03-23 00:44:22 +0000 |
commit | 8fff11068c100be627745967992fb88759dea9c1 (patch) | |
tree | 9d1147377847b5a22a9e38d945b3a8dd4d673475 | |
parent | 7d0f5c1aca332da22e4878f5825e0ffb5122f96b (diff) | |
download | e2fsprogs-8fff11068c100be627745967992fb88759dea9c1.tar.gz |
ext2simg: clean up integer types and check for too-large fs
libsparse assumes 32-bit block numbers. Also, ext2simg might read
nearly the entire filesystem into memory.
Therefore, make ext2simg use appropriate integer types, and explicitly
check for when the filesystem is too large or allocating memory failed.
Change-Id: Ic415d0e974dce2b4ff6e7fa9265f6e86d371a274
Signed-off-by: Eric Biggers <ebiggers@google.com>
-rw-r--r-- | contrib/android/ext2simg.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/contrib/android/ext2simg.c b/contrib/android/ext2simg.c index 811c60d6..13a9d567 100644 --- a/contrib/android/ext2simg.c +++ b/contrib/android/ext2simg.c @@ -80,7 +80,11 @@ static void add_chunk(ext2_filsys fs, struct sparse_file *s, } /* The input file will be overwritten, so make a copy of the blocks. */ + if (len > SIZE_MAX - sizeof(*bi)) + sparse_fatal("filesystem is too large"); bi = calloc(1, sizeof(*bi) + len); + if (!bi) + sparse_fatal("out of memory"); bi->next = buf_list; buf_list = bi; retval = io_channel_read_blk64(fs->io, chunk_start, num_blks, bi->buf); @@ -102,6 +106,16 @@ static void free_chunks(void) } } +static blk_t fs_blocks_count(ext2_filsys fs) +{ + blk64_t blks = ext2fs_blocks_count(fs->super); + + /* libsparse assumes 32-bit block numbers. */ + if ((blk_t)blks != blks) + sparse_fatal("filesystem is too large"); + return blks; +} + static struct sparse_file *ext_to_sparse(const char *in_file) { errcode_t retval; @@ -118,7 +132,7 @@ static struct sparse_file *ext_to_sparse(const char *in_file) if (retval) ext2fs_fatal(retval, "while reading block bitmap of %s", in_file); - fs_blks = ext2fs_blocks_count(fs->super); + fs_blks = fs_blocks_count(fs); s = sparse_file_new(fs->blocksize, (uint64_t)fs_blks * fs->blocksize); if (!s) @@ -132,7 +146,7 @@ static struct sparse_file *ext_to_sparse(const char *in_file) * larger than INT32_MAX (32-bit _and_ 64-bit systems). * Make sure we do not create chunks larger than this limit. */ - int64_t max_blk_per_chunk = (INT32_MAX - 12) / fs->blocksize; + int32_t max_blk_per_chunk = (INT32_MAX - 12) / fs->blocksize; /* * Iterate through the filesystem's blocks, identifying "chunks" that |