]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Avoid crashing on unaligned pointers from corrupted file systems
authorTheodore Ts'o <tytso@mit.edu>
Sun, 4 Sep 2016 19:06:32 +0000 (15:06 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 4 Sep 2016 19:06:32 +0000 (15:06 -0400)
On platforms that don't permit unaligned pointer dereferences,
corrupted file systems will as used by the regression test suite can
cause e2fsck and debugfs to crash.  Avoid those crashes caused by
corrupted file systems.  With this commit the full set of regression
test suites will pass on the sparc64 platform.

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

index 48f42b73f44466b99b707930cb55db1fa06bb552..abf12c71ef2e65045442157656896a8a6ab32b63 100644 (file)
@@ -338,12 +338,24 @@ int journal_skip_recovery(journal_t *journal)
        return err;
 }
 
+static inline __u32 get_be32(__be32 *p)
+{
+       unsigned char *cp = (unsigned char *) p;
+       __u32 ret;
+
+       ret = *cp++;
+       ret = (ret << 8) + *cp++;
+       ret = (ret << 8) + *cp++;
+       ret = (ret << 8) + *cp++;
+       return ret;
+}
+
 static inline unsigned long long read_tag_block(journal_t *journal,
                                                journal_block_tag_t *tag)
 {
-       unsigned long long block = ext2fs_be32_to_cpu(tag->t_blocknr);
+       unsigned long long block = get_be32(&tag->t_blocknr);
        if (jfs_has_feature_64bit(journal))
-               block |= (u64)ext2fs_be32_to_cpu(tag->t_blocknr_high) << 32;
+               block |= (u64)get_be32(&tag->t_blocknr_high) << 32;
        return block;
 }
 
index 4389a2fcbe593e05a5be0968a65bbeb9f7b28f32..ac8084904c3e5500f583abf49846646df48ca722 100644 (file)
@@ -185,8 +185,9 @@ struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
                                          struct opaque_ext2_group_desc *gdp,
                                          dgrp_t group)
 {
-       return (struct ext2_group_desc *)((char *)gdp +
-                                         group * EXT2_DESC_SIZE(fs->super));
+       int desc_size = EXT2_DESC_SIZE(fs->super) & ~7;
+
+       return (struct ext2_group_desc *)((char *)gdp + group * desc_size);
 }
 
 /* Do the same but as an ext4 group desc for internal use here */
index b769eb09366bee99b8d2eacea3ed5680e916a44c..d63fc55fd49612381ad5bf8030f0f7daa68ee7cc 100644 (file)
@@ -307,6 +307,8 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
                /* this is error case: i_extra_size is too large */
                return;
        }
+       if (extra_isize & 3)
+               return;         /* Illegal inode extra_isize */
 
        inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize;
        if (inode_includes(inode_size, i_checksum_hi))