ext2simg: fix off-by-one errors causing corruption
The chunk_end parameter to add_chunk() is exclusive, but two callers
incorrectly treat it as inclusive: when the maximum chunk length of
'INT32_MAX - 12' bytes is reached, and when a chunk extends to the very
end of the filesystem. The result is that the output simg file contains
zeroes for the last block of these chunks instead of the correct data.
A related bug is that the expanded size of the simg file is set to the
filesystem size (in blocks) minus s_first_data_block. On filesystems
where s_first_data_block != 0, i.e. 1K blocksize filesystems without
bigalloc enabled, this truncates the last block of the filesystem.
Fix these bugs by (a) making add_chunk() take the chunk length and
passing the correct values, and (b) using the filesystem size properly.
Here is a reproducer that shows the last block of the filesystem being
truncated (bsize=1024) and being corrupted with zeroes (bsize=4096):
for bsize in 1024 4096; do
rm -f ext4.img
mkfs.ext4 -b $bsize ext4.img 10000
mkdir -p mnt
sudo mount -t ext4 -o loop ext4.img mnt
sudo cp /dev/urandom mnt/fill
sudo umount mnt
ext2simg ext4.img ext4.simg
simg2img ext4.simg ext4.img.restored
cmp ext4.img ext4.img.restored
done
Fixes: db6f320912cf ("AOSP: android: add the ext2simg tool")
Reported-by: Clemens Lang <clemens.lang@bmw.de>
Change-Id: I3b64c4fbffa5821b431f29e99b36168617da7563
Signed-off-by: Eric Biggers <ebiggers@google.com>
1 file changed