Commit 2dcf838c authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba
Browse files

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: b4c50cbb ("btrfs: return a btrfs_inode from read_one_inode()")
CC: stable@vger.kernel.org # 6.15+
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent e5b55960
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -668,15 +668,12 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
		extent_end = ALIGN(start + size,
				   fs_info->sectorsize);
	} else {
		ret = 0;
		goto out;
		return 0;
	}

	inode = read_one_inode(root, key->objectid);
	if (!inode) {
		ret = -EIO;
		goto out;
	}
	if (!inode)
		return -EIO;

	/*
	 * first check to see if we already have this extent in the
@@ -961,6 +958,7 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
	ret = unlink_inode_for_log_replay(trans, dir, inode, &name);
out:
	kfree(name.name);
	if (inode)
		iput(&inode->vfs_inode);
	return ret;
}
@@ -1176,8 +1174,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
					ret = unlink_inode_for_log_replay(trans,
							victim_parent,
							inode, &victim_name);
				}
					iput(&victim_parent->vfs_inode);
				}
				kfree(victim_name.name);
				if (ret)
					return ret;