Whamcloud - gitweb
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 48f42b7..abf12c7 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 4389a2f..ac80849 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 b769eb0..d63fc55 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))