提交 381cf658 编写于 作者: D David Sterba

btrfs: fix leak of path in btrfs_find_item

If btrfs_find_item is called with NULL path it allocates one locally but
does not free it. Affected paths are inserting an orphan item for a file
and for a subvol root.

Move the path allocation to the callers.

CC: <stable@vger.kernel.org> # 3.14+
Fixes: 3f870c28 ("btrfs: expand btrfs_find_item() to include find_orphan_item functionality")
Signed-off-by: NDavid Sterba <dsterba@suse.cz>
上级 eaa27f34
...@@ -2609,32 +2609,23 @@ static int key_search(struct extent_buffer *b, struct btrfs_key *key, ...@@ -2609,32 +2609,23 @@ static int key_search(struct extent_buffer *b, struct btrfs_key *key,
return 0; return 0;
} }
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
u64 iobjectid, u64 ioff, u8 key_type, u64 iobjectid, u64 ioff, u8 key_type,
struct btrfs_key *found_key) struct btrfs_key *found_key)
{ {
int ret; int ret;
struct btrfs_key key; struct btrfs_key key;
struct extent_buffer *eb; struct extent_buffer *eb;
struct btrfs_path *path;
ASSERT(path);
key.type = key_type; key.type = key_type;
key.objectid = iobjectid; key.objectid = iobjectid;
key.offset = ioff; key.offset = ioff;
if (found_path == NULL) {
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
} else
path = found_path;
ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0); ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
if ((ret < 0) || (found_key == NULL)) { if ((ret < 0) || (found_key == NULL))
if (path != found_path)
btrfs_free_path(path);
return ret; return ret;
}
eb = path->nodes[0]; eb = path->nodes[0];
if (ret && path->slots[0] >= btrfs_header_nritems(eb)) { if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
......
...@@ -1630,6 +1630,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, ...@@ -1630,6 +1630,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
bool check_ref) bool check_ref)
{ {
struct btrfs_root *root; struct btrfs_root *root;
struct btrfs_path *path;
int ret; int ret;
if (location->objectid == BTRFS_ROOT_TREE_OBJECTID) if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
...@@ -1669,8 +1670,14 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, ...@@ -1669,8 +1670,14 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
if (ret) if (ret)
goto fail; goto fail;
ret = btrfs_find_item(fs_info->tree_root, NULL, BTRFS_ORPHAN_OBJECTID, path = btrfs_alloc_path();
if (!path) {
ret = -ENOMEM;
goto fail;
}
ret = btrfs_find_item(fs_info->tree_root, path, BTRFS_ORPHAN_OBJECTID,
location->objectid, BTRFS_ORPHAN_ITEM_KEY, NULL); location->objectid, BTRFS_ORPHAN_ITEM_KEY, NULL);
btrfs_free_path(path);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
if (ret == 0) if (ret == 0)
......
...@@ -1257,10 +1257,19 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans, ...@@ -1257,10 +1257,19 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 offset) struct btrfs_root *root, u64 offset)
{ {
int ret; int ret;
ret = btrfs_find_item(root, NULL, BTRFS_ORPHAN_OBJECTID, struct btrfs_path *path;
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
ret = btrfs_find_item(root, path, BTRFS_ORPHAN_OBJECTID,
offset, BTRFS_ORPHAN_ITEM_KEY, NULL); offset, BTRFS_ORPHAN_ITEM_KEY, NULL);
if (ret > 0) if (ret > 0)
ret = btrfs_insert_orphan_item(trans, root, offset); ret = btrfs_insert_orphan_item(trans, root, offset);
btrfs_free_path(path);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册