diff options
author | Colin Ian King <colin.king@canonical.com> | 2019-07-05 03:26:24 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2019-07-05 12:47:57 -0400 |
commit | e02d48eaaed77f6c36916a7aa65c451e1f9d9aab (patch) | |
tree | 59aec3f4273813834a2259005c104c1ec92ff919 | |
parent | 28a32d2b1a6d7860e0b364c34a6b4205dce85537 (diff) |
btrfs: fix memory leak of path on error return path
Currently if the allocation of roots or tmp_ulist fails the error handling
does not free up the allocation of path causing a memory leak. Fix this and
other similar leaks by moving the call of btrfs_free_path from label out
to label out_free_ulist.
Kudos to David Sterba for spotting the issue in my original fix and suggesting
the correct way to fix the leak and Anand Jain for spotting a double free
issue.
Addresses-Coverity: ("Resource leak")
Fixes: 5911c8fe05c5 ("btrfs: fiemap: preallocate ulists for btrfs_check_shared")
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/extent_io.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 6b154bce5687..aea990473392 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -4611,7 +4611,6 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4611 | ret = btrfs_lookup_file_extent(NULL, root, path, | 4611 | ret = btrfs_lookup_file_extent(NULL, root, path, |
4612 | btrfs_ino(BTRFS_I(inode)), -1, 0); | 4612 | btrfs_ino(BTRFS_I(inode)), -1, 0); |
4613 | if (ret < 0) { | 4613 | if (ret < 0) { |
4614 | btrfs_free_path(path); | ||
4615 | goto out_free_ulist; | 4614 | goto out_free_ulist; |
4616 | } else { | 4615 | } else { |
4617 | WARN_ON(!ret); | 4616 | WARN_ON(!ret); |
@@ -4764,11 +4763,11 @@ out_free: | |||
4764 | ret = emit_last_fiemap_cache(fieinfo, &cache); | 4763 | ret = emit_last_fiemap_cache(fieinfo, &cache); |
4765 | free_extent_map(em); | 4764 | free_extent_map(em); |
4766 | out: | 4765 | out: |
4767 | btrfs_free_path(path); | ||
4768 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, | 4766 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, |
4769 | &cached_state); | 4767 | &cached_state); |
4770 | 4768 | ||
4771 | out_free_ulist: | 4769 | out_free_ulist: |
4770 | btrfs_free_path(path); | ||
4772 | ulist_free(roots); | 4771 | ulist_free(roots); |
4773 | ulist_free(tmp_ulist); | 4772 | ulist_free(tmp_ulist); |
4774 | return ret; | 4773 | return ret; |