--- /dev/null
+From 4f26433e9b3eb7a55ed70d8f882ae9cd48ba448b Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 29 Jul 2020 10:17:50 +0100
+Subject: btrfs: fix memory leaks after failure to lookup checksums during inode logging
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 4f26433e9b3eb7a55ed70d8f882ae9cd48ba448b upstream.
+
+While logging an inode, at copy_items(), if we fail to lookup the checksums
+for an extent we release the destination path, free the ins_data array and
+then return immediately. However a previous iteration of the for loop may
+have added checksums to the ordered_sums list, in which case we leak the
+memory used by them.
+
+So fix this by making sure we iterate the ordered_sums list and free all
+its checksums before returning.
+
+Fixes: 3650860b90cc2a ("Btrfs: remove almost all of the BUG()'s from tree-log.c")
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3854,11 +3854,8 @@ static noinline int copy_items(struct bt
+ fs_info->csum_root,
+ ds + cs, ds + cs + cl - 1,
+ &ordered_sums, 0);
+- if (ret) {
+- btrfs_release_path(dst_path);
+- kfree(ins_data);
+- return ret;
+- }
++ if (ret)
++ break;
+ }
+ }
+ }
+@@ -3871,7 +3868,6 @@ static noinline int copy_items(struct bt
+ * we have to do this after the loop above to avoid changing the
+ * log tree while trying to change the log tree.
+ */
+- ret = 0;
+ while (!list_empty(&ordered_sums)) {
+ struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
+ struct btrfs_ordered_sum,
--- /dev/null
+From bf53d4687b8f3f6b752f091eb85f62369a515dfd Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 27 Jul 2020 10:28:05 -0400
+Subject: btrfs: only search for left_info if there is no right_info in try_merge_free_space
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit bf53d4687b8f3f6b752f091eb85f62369a515dfd upstream.
+
+In try_to_merge_free_space we attempt to find entries to the left and
+right of the entry we are adding to see if they can be merged. We
+search for an entry past our current info (saved into right_info), and
+then if right_info exists and it has a rb_prev() we save the rb_prev()
+into left_info.
+
+However there's a slight problem in the case that we have a right_info,
+but no entry previous to that entry. At that point we will search for
+an entry just before the info we're attempting to insert. This will
+simply find right_info again, and assign it to left_info, making them
+both the same pointer.
+
+Now if right_info _can_ be merged with the range we're inserting, we'll
+add it to the info and free right_info. However further down we'll
+access left_info, which was right_info, and thus get a use-after-free.
+
+Fix this by only searching for the left entry if we don't find a right
+entry at all.
+
+The CVE referenced had a specially crafted file system that could
+trigger this use-after-free. However with the tree checker improvements
+we no longer trigger the conditions for the UAF. But the original
+conditions still apply, hence this fix.
+
+Reference: CVE-2019-19448
+Fixes: 963030817060 ("Btrfs: use hybrid extents+bitmap rb tree for free space")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/free-space-cache.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -2169,7 +2169,7 @@ out:
+ static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info, bool update_stat)
+ {
+- struct btrfs_free_space *left_info;
++ struct btrfs_free_space *left_info = NULL;
+ struct btrfs_free_space *right_info;
+ bool merged = false;
+ u64 offset = info->offset;
+@@ -2184,7 +2184,7 @@ static bool try_merge_free_space(struct
+ if (right_info && rb_prev(&right_info->offset_index))
+ left_info = rb_entry(rb_prev(&right_info->offset_index),
+ struct btrfs_free_space, offset_index);
+- else
++ else if (!right_info)
+ left_info = tree_search_offset(ctl, offset - 1, 0, 0);
+
+ if (right_info && !right_info->bitmap) {