[v2] btrfs: only search for left_info if there is no right_info
diff mbox series

Message ID 20200722184537.19896-1-josef@toxicpanda.com
State New
Headers show
Series
  • [v2] btrfs: only search for left_info if there is no right_info
Related show

Commit Message

Josef Bacik July 22, 2020, 6:45 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
happen.

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
be.

Reference: CVE-2019-19448
Fixes: 963030817060 ("Btrfs: use hybrid extents+bitmap rb tree for free space")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
v1->v2:
- Fixed the title, I had changed the fix but forgot to change the title in v1

 fs/btrfs/free-space-cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

David Sterba July 27, 2020, 11:55 a.m. UTC | #1
On Wed, Jul 22, 2020 at 02:45:37PM -0400, Josef Bacik wrote:
> The CVE referenced doesn't actually trigger the problem anymore because
> of the tree-checker improvements, however the underlying issue can still
> happen.

What was the problem?

> 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
> be.
> 
> Reference: CVE-2019-19448
> Fixes: 963030817060 ("Btrfs: use hybrid extents+bitmap rb tree for free space")
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
> v1->v2:
> - Fixed the title, I had changed the fix but forgot to change the title in v1

The title still repeats what the code does and left_info or right_info
are not terms that are understood without context (unlike eg. fs_info)

Patch
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. */