All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolay Borisov <nborisov@suse.com>
To: Josef Bacik <josef@toxicpanda.com>,
	linux-btrfs@vger.kernel.org, kernel-team@fb.com
Cc: stable@vger.kernel.org
Subject: Re: [PATCH] btrfs: avoid double put of block group when emptying cluster
Date: Tue, 26 Jan 2021 11:02:41 +0200	[thread overview]
Message-ID: <bf8cd92d-12a0-3bb3-34c0-dd9c938bf349@suse.com> (raw)
In-Reply-To: <5ca694ff4f8cff4c0ef6896593a1f1d01fbe956d.1611610947.git.josef@toxicpanda.com>



On 25.01.21 г. 23:42 ч., Josef Bacik wrote:
> In __btrfs_return_cluster_to_free_space we will bail doing the cleanup
> of the cluster if the block group we passed in doesn't match the block
> group on the cluster.  However we drop a reference to block_group, as
> the cluster holds a reference to the block group while it's attached to
> the cluster.  If cluster->block_group != block_group however then this
> is an extra put, which means we'll go negative and free this block group
> down the line, leading to a UAF.

Was this found by code inspection or did you hit in production. Also why
in btrfs_remove_free_space_cache just before
__btrfs_return_cluster_to_free_space there is:

WARN_ON(cluster->block_group != block_group);

IMO this patch should also remove the WARN_ON if it's a valid condition
to have the passed bg be different than the one in the cluster. Also
that WARN_ON is likely racy since it's done outside of cluster->lock.

> 
> Fix this by simply bailing if the block group we passed in does not
> match the block group on the cluster.
> 
> CC: stable@vger.kernel.org
> Fixes: fa9c0d795f7b ("Btrfs: rework allocation clustering")
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/free-space-cache.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
> index 0d6dcb5ff963..8be36cc6cbd8 100644
> --- a/fs/btrfs/free-space-cache.c
> +++ b/fs/btrfs/free-space-cache.c
> @@ -2711,8 +2711,10 @@ static void __btrfs_return_cluster_to_free_space(
>  	struct rb_node *node;
>  
>  	spin_lock(&cluster->lock);
> -	if (cluster->block_group != block_group)
> -		goto out;
> +	if (cluster->block_group != block_group) {
> +		spin_unlock(&cluster->lock);
> +		return;
> +	}
>  
>  	cluster->block_group = NULL;
>  	cluster->window_start = 0;
> @@ -2750,8 +2752,6 @@ static void __btrfs_return_cluster_to_free_space(
>  				   entry->offset, &entry->offset_index, bitmap);
>  	}
>  	cluster->root = RB_ROOT;
> -
> -out:
>  	spin_unlock(&cluster->lock);
>  	btrfs_put_block_group(block_group);
>  }
> 

  reply	other threads:[~2021-01-26  9:03 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-25 21:42 [PATCH] btrfs: avoid double put of block group when emptying cluster Josef Bacik
2021-01-26  9:02 ` Nikolay Borisov [this message]
2021-01-26 14:30   ` Josef Bacik
2021-02-10 22:50     ` David Sterba
2021-02-11 11:25       ` Nikolay Borisov
2021-02-17 17:29         ` David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bf8cd92d-12a0-3bb3-34c0-dd9c938bf349@suse.com \
    --to=nborisov@suse.com \
    --cc=josef@toxicpanda.com \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.