aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2023-03-23 00:44:22 +0000
committerEric Biggers <ebiggers@google.com>2023-03-23 00:44:22 +0000
commit8fff11068c100be627745967992fb88759dea9c1 (patch)
tree9d1147377847b5a22a9e38d945b3a8dd4d673475
parent7d0f5c1aca332da22e4878f5825e0ffb5122f96b (diff)
downloade2fsprogs-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.c18
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