Skip to content

Commit 7f6ece7

Browse files
fdmananakdave
authored andcommitted
btrfs: fix invalid inode pointer dereferences during log replay
In a few places where we call read_one_inode(), if we get a NULL pointer we end up jumping into an error path, or fallthrough in case of __add_inode_ref(), where we then do something like this: iput(&inode->vfs_inode); which results in an invalid inode pointer that triggers an invalid memory access, resulting in a crash. Fix this by making sure we don't do such dereferences. Fixes: b4c50cb ("btrfs: return a btrfs_inode from read_one_inode()") CC: stable@vger.kernel.org # 6.15+ Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent ab31321 commit 7f6ece7

File tree

1 file changed

+6
-8
lines changed

1 file changed

+6
-8
lines changed

fs/btrfs/tree-log.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -668,15 +668,12 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
668668
extent_end = ALIGN(start + size,
669669
fs_info->sectorsize);
670670
} else {
671-
ret = 0;
672-
goto out;
671+
return 0;
673672
}
674673

675674
inode = read_one_inode(root, key->objectid);
676-
if (!inode) {
677-
ret = -EIO;
678-
goto out;
679-
}
675+
if (!inode)
676+
return -EIO;
680677

681678
/*
682679
* first check to see if we already have this extent in the
@@ -961,7 +958,8 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
961958
ret = unlink_inode_for_log_replay(trans, dir, inode, &name);
962959
out:
963960
kfree(name.name);
964-
iput(&inode->vfs_inode);
961+
if (inode)
962+
iput(&inode->vfs_inode);
965963
return ret;
966964
}
967965

@@ -1176,8 +1174,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
11761174
ret = unlink_inode_for_log_replay(trans,
11771175
victim_parent,
11781176
inode, &victim_name);
1177+
iput(&victim_parent->vfs_inode);
11791178
}
1180-
iput(&victim_parent->vfs_inode);
11811179
kfree(victim_name.name);
11821180
if (ret)
11831181
return ret;

0 commit comments

Comments
 (0)