aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2021-05-06 22:40:57 -0400
committerTheodore Ts'o <tytso@mit.edu>2021-05-06 22:40:57 -0400
commit86fe64e48631dbe330355b8127d816957baff52b (patch)
tree89673272e3ff67916f364868527b2467feb77207
parent45780b37ef2ad6142ab882a85b90e608c5b6f0c3 (diff)
downloade2fsprogs-86fe64e48631dbe330355b8127d816957baff52b.tar.gz
e2fsck: fix unaligned accesses to ext4_fc_add_range and fc_raw_inode
These fast commit related structures can be unaligned on disk. So we need to avoid accessing these structures directly, and first copy them to memory which we know is appropriately aligned. This fixes an e2fsck crash while running the j_recovery_fast_commit regression test on a sparc64 system. Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--e2fsck/journal.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/e2fsck/journal.c b/e2fsck/journal.c
index ae3df800d..0128fbd39 100644
--- a/e2fsck/journal.c
+++ b/e2fsck/journal.c
@@ -284,7 +284,7 @@ static int ext4_fc_replay_scan(journal_t *j, struct buffer_head *bh,
e2fsck_t ctx = j->j_fs_dev->k_ctx;
struct e2fsck_fc_replay_state *state;
int ret = JBD2_FC_REPLAY_CONTINUE;
- struct ext4_fc_add_range *ext;
+ struct ext4_fc_add_range ext;
struct ext4_fc_tl tl;
struct ext4_fc_tail tail;
__u8 *start, *cur, *end, *val;
@@ -321,9 +321,10 @@ static int ext4_fc_replay_scan(journal_t *j, struct buffer_head *bh,
tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
switch (le16_to_cpu(tl.fc_tag)) {
case EXT4_FC_TAG_ADD_RANGE:
- ext = (struct ext4_fc_add_range *)val;
- ret = ext2fs_decode_extent(&ext2fs_ex, (void *)&ext->fc_ex,
- sizeof(ext->fc_ex));
+ memcpy(&ext, val, sizeof(ext));
+ ret = ext2fs_decode_extent(&ext2fs_ex,
+ (void *)&ext.fc_ex,
+ sizeof(ext.fc_ex));
if (ret)
ret = JBD2_FC_REPLAY_STOP;
else
@@ -764,12 +765,9 @@ static int ext4_fc_handle_inode(e2fsck_t ctx, __u8 *val)
inode_len);
if (err)
goto out;
-#ifdef WORDS_BIGENDIAN
- ext2fs_swap_inode_full(ctx->fs, fc_inode,
- (struct ext2_inode_large *)fc_raw_inode,
- 0, sizeof(*inode));
-#else
memcpy(fc_inode, fc_raw_inode, inode_len);
+#ifdef WORDS_BIGENDIAN
+ ext2fs_swap_inode_full(ctx->fs, fc_inode, fc_inode, 0, inode_len);
#endif
memcpy(inode, fc_inode, offsetof(struct ext2_inode_large, i_block));
memcpy(&inode->i_generation, &fc_inode->i_generation,