Whamcloud - gitweb
libext2fs: fix crash in ext2fs_image_super_write() on Big Endian systems
authorTheodore Ts'o <tytso@mit.edu>
Tue, 14 Jan 2020 15:58:10 +0000 (10:58 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 14 Jan 2020 15:58:10 +0000 (10:58 -0500)
This is a similar fix as c9a8c53b17cc ("libext2fs: fix crash in
ext2fs_open2() on Big Endian systems").

Commit e6069a05: ("Teach ext2fs_open2() to honor the
EXT2_FLAG_SUPER_ONLY flag") changed how the function
ext2fs_group_desc() handled a request for a gdp pointer for a group
larger than the number of groups in the file system; it now returns
NULL, instead of returning a pointer beyond the end of the array.

Previously, the ext2fs_imager_super_write() function would swap all of
the block group descriptors in a block, even if they are beyond the
end of the file system.  This was OK, since we were not overrunning
the allocated memory, since it was rounded to a block boundary.  But
now that ext2fs_group_desc() would return NULL for those gdp, it would
cause ext2fs_open2(), when it was byte swapping the block group
descriptors on Big Endian systems, to dereference a null pointer and
crash.

This commit adds a NULL pointer check to avoid byte swapping those
block group descriptors in a bg descriptor block, but which are beyond
the end of the file system, to address this crash.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reported-by: Anatoly Pugachev <matorola@gmail.com>
lib/ext2fs/imager.c

index 7fd06f7..64a55be 100644 (file)
@@ -242,10 +242,10 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd,
         * if needed
         */
        groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
-       gdp = (struct ext2_group_desc *) cp;
        for (j=0; j < groups_per_block*fs->desc_blocks; j++) {
                gdp = ext2fs_group_desc(fs, fs->group_desc, j);
-               ext2fs_swap_group_desc2(fs, gdp);
+               if (gdp)
+                       ext2fs_swap_group_desc2(fs, gdp);
        }
 #endif
 
@@ -254,10 +254,10 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd,
 
 #ifdef WORDS_BIGENDIAN
        groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
-       gdp = (struct ext2_group_desc *) cp;
        for (j=0; j < groups_per_block*fs->desc_blocks; j++) {
                gdp = ext2fs_group_desc(fs, fs->group_desc, j);
-               ext2fs_swap_group_desc2(fs, gdp);
+               if (gdp)
+                       ext2fs_swap_group_desc2(fs, gdp);
        }
 #endif