diff options
author | David Sterba <dsterba@suse.cz> | 2015-01-02 12:45:16 -0500 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2015-01-14 13:23:46 -0500 |
commit | 381cf6587f8a8a8e981bc0c1aaaa8859b51dc756 (patch) | |
tree | 024b49bf7f036ff79846076c44710337bd0d5ec1 /fs/btrfs/ctree.c | |
parent | eaa27f34e91a14cdceed26ed6c6793ec1d186115 (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/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 17 |
1 files changed, 4 insertions, 13 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 | ||
2612 | int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, | 2612 | int 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)) { |