btrfs: unset left_info if it matches right_info
diff mbox series

Message ID
State New
Headers show
  • btrfs: unset left_info if it matches right_info
Related show

Commit Message

Josef Bacik July 22, 2020, 6:42 p.m. UTC
The CVE referenced doesn't actually trigger the problem anymore because
of the tree-checker improvements, however the underlying issue can still

If we find a right_info, but rb_prev() is NULL, then we're the furthest
most item in the tree currently, and there will be no left_info.
However we'll still search from offset-1, which would return right_info
again which we store in left_info.  If we then free right_info we'll
have free'd left_info as well, and boom, UAF.  Instead fix this check so
that if we don't have a right_info we do the search for the left_info,
otherwise left_info comes from rb_prev or is simply NULL as it should

Reference: CVE-2019-19448
Fixes: 963030817060 ("Btrfs: use hybrid extents+bitmap rb tree for free space")
Signed-off-by: Josef Bacik <>
 fs/btrfs/free-space-cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff mbox series

diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 6d961e11639e..37fd2fa1ac1f 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -2298,7 +2298,7 @@  static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
 	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);
 	/* See try_merge_free_space() comment. */