]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: avoid looping forever in e2image when superblock is invalid
authorTheodore Ts'o <tytso@mit.edu>
Sat, 13 Aug 2022 20:39:17 +0000 (16:39 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 13 Aug 2022 20:39:17 +0000 (16:39 -0400)
If the number of blocks or inodes per block group is not a multiple of
8 (which are invalid values) ext2fs_image_bitmap{read,write} can loop
forever.  These file systems should be not be allowed to be opened
(without EXT2_FLAG_IGNORE_SB_ERRORS) but for the fact that a long time
ago, Android devices used a buggy (but BSD-licensed, which was what
was important to the early Android founders) program for creating file
systems which would create these invalid file systems.  E2fsck
couldn't actually correctly repair these file systems, but adding a
check to enforce this (in e2fsprogs and in the kernel) would have
broken some of these devices, so support for these bogus file system
was in a grey area for many years.

We will be tightening this up soon, but for now, we'll apply this
quick fix so attempts to use e2image won't hang forever.  (Not that
Android ever shipped e2image in those days, of course...)

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/imager.c

index 6f8582a885ce9513e7cf79163afc8e9f3da35936..23290a6a2bd7d5ae4f3585266b42e8e7b0b2b64a 100644 (file)
@@ -372,6 +372,8 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
                size = sizeof(buf);
                if (size > (cnt >> 3))
                        size = (cnt >> 3);
+               if (size == 0)
+                       break;
 
                retval = ext2fs_get_generic_bmap_range(bmap, itr,
                                                       size << 3, buf);
@@ -447,6 +449,8 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
                size = sizeof(buf);
                if (size > (cnt >> 3))
                        size = (cnt >> 3);
+               if (size == 0)
+                       break;
 
                actual = read(fd, buf, size);
                if (actual == -1)