aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2015-01-02 12:45:16 -0500
committerDavid Sterba <dsterba@suse.cz>2015-01-14 13:23:46 -0500
commit381cf6587f8a8a8e981bc0c1aaaa8859b51dc756 (patch)
tree024b49bf7f036ff79846076c44710337bd0d5ec1 /fs
parenteaa27f34e91a14cdceed26ed6c6793ec1d186115 (diff)
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: 3f870c289900 ("btrfs: expand btrfs_find_item() to include find_orphan_item functionality") Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.c17
-rw-r--r--fs/btrfs/disk-io.c9
-rw-r--r--fs/btrfs/tree-log.c11
3 files changed, 22 insertions, 15 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 14a72ed14ef7..f54511dd287e 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2609,32 +2609,23 @@ static int key_search(struct extent_buffer *b, struct btrfs_key *key,
2609 return 0; 2609 return 0;
2610} 2610}
2611 2611
2612int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, 2612int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
2613 u64 iobjectid, u64 ioff, u8 key_type, 2613 u64 iobjectid, u64 ioff, u8 key_type,
2614 struct btrfs_key *found_key) 2614 struct btrfs_key *found_key)
2615{ 2615{
2616 int ret; 2616 int ret;
2617 struct btrfs_key key; 2617 struct btrfs_key key;
2618 struct extent_buffer *eb; 2618 struct extent_buffer *eb;
2619 struct btrfs_path *path; 2619
2620 ASSERT(path);
2620 2621
2621 key.type = key_type; 2622 key.type = key_type;
2622 key.objectid = iobjectid; 2623 key.objectid = iobjectid;
2623 key.offset = ioff; 2624 key.offset = ioff;
2624 2625
2625 if (found_path == NULL) {
2626 path = btrfs_alloc_path();
2627 if (!path)
2628 return -ENOMEM;
2629 } else
2630 path = found_path;
2631
2632 ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0); 2626 ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
2633 if ((ret < 0) || (found_key == NULL)) { 2627 if ((ret < 0) || (found_key == NULL))
2634 if (path != found_path)
2635 btrfs_free_path(path);
2636 return ret; 2628 return ret;
2637 }
2638 2629
2639 eb = path->nodes[0]; 2630 eb = path->nodes[0];
2640 if (ret && path->slots[0] >= btrfs_header_nritems(eb)) { 2631 if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8c63419a7f70..6182e5493d0f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1630,6 +1630,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
1630 bool check_ref) 1630 bool check_ref)
1631{ 1631{
1632 struct btrfs_root *root; 1632 struct btrfs_root *root;
1633 struct btrfs_path *path;
1633 int ret; 1634 int ret;
1634 1635
1635 if (location->objectid == BTRFS_ROOT_TREE_OBJECTID) 1636 if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
@@ -1669,8 +1670,14 @@ again:
1669 if (ret) 1670 if (ret)
1670 goto fail; 1671 goto fail;
1671 1672
1672 ret = btrfs_find_item(fs_info->tree_root, NULL, BTRFS_ORPHAN_OBJECTID, 1673 path = btrfs_alloc_path();
1674 if (!path) {
1675 ret = -ENOMEM;
1676 goto fail;
1677 }
1678 ret = btrfs_find_item(fs_info->tree_root, path, BTRFS_ORPHAN_OBJECTID,
1673 location->objectid, BTRFS_ORPHAN_ITEM_KEY, NULL); 1679 location->objectid, BTRFS_ORPHAN_ITEM_KEY, NULL);
1680 btrfs_free_path(path);
1674 if (ret < 0) 1681 if (ret < 0)
1675 goto fail; 1682 goto fail;
1676 if (ret == 0) 1683 if (ret == 0)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 9a02da16f2be..5be45c12dd71 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1257,10 +1257,19 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans,
1257 struct btrfs_root *root, u64 offset) 1257 struct btrfs_root *root, u64 offset)
1258{ 1258{
1259 int ret; 1259 int ret;
1260 ret = btrfs_find_item(root, NULL, BTRFS_ORPHAN_OBJECTID, 1260 struct btrfs_path *path;
1261
1262 path = btrfs_alloc_path();
1263 if (!path)
1264 return -ENOMEM;
1265
1266 ret = btrfs_find_item(root, path, BTRFS_ORPHAN_OBJECTID,
1261 offset, BTRFS_ORPHAN_ITEM_KEY, NULL); 1267 offset, BTRFS_ORPHAN_ITEM_KEY, NULL);
1262 if (ret > 0) 1268 if (ret > 0)
1263 ret = btrfs_insert_orphan_item(trans, root, offset); 1269 ret = btrfs_insert_orphan_item(trans, root, offset);
1270
1271 btrfs_free_path(path);
1272
1264 return ret; 1273 return ret;
1265} 1274}
1266 1275