From 87acb4ef9b2991e1c453b78d71bce2ef994ef1ff Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 18 Aug 2008 22:50:22 +0100 Subject: [PATCH] Simplify btrfs_get_parent(), fix use-after-free bug Date: Mon, 18 Aug 2008 22:50:22 +0100 Signed-off-by: David Woodhouse Signed-off-by: Chris Mason --- fs/btrfs/export.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 797b4cbc3786..a913b9befe68 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c @@ -147,7 +147,6 @@ static struct dentry *btrfs_get_parent(struct dentry *child) struct btrfs_key key; struct btrfs_path *path; struct extent_buffer *leaf; - u32 nritems; int slot; u64 objectid; int ret; @@ -156,27 +155,24 @@ static struct dentry *btrfs_get_parent(struct dentry *child) key.objectid = dir->i_ino; btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); - key.offset = 0; - ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); - BUG_ON(ret == 0); - ret = 0; + key.offset = (u64)-1; + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); leaf = path->nodes[0]; slot = path->slots[0]; - nritems = btrfs_header_nritems(leaf); - if (slot >= nritems) { - ret = btrfs_next_leaf(root, path); - if (ret) { - btrfs_free_path(path); - goto out; - } - leaf = path->nodes[0]; - slot = path->slots[0]; + if (ret < 0 || slot == 0) { + btrfs_free_path(path); + goto out; } + /* btrfs_search_slot() returns the slot where we'd want to insert + an INODE_REF_KEY for parent inode #0xFFFFFFFFFFFFFFFF. The _real_ + one, telling us what the parent inode _actually_ is, will be in + the slot _before_ the one that btrfs_search_slot() returns. */ + slot--; + btrfs_item_key_to_cpu(leaf, &key, slot); btrfs_free_path(path); - btrfs_item_key_to_cpu(leaf, &key, slot); if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY) goto out; -- 2.20.1