mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.cz>
To: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Cc: Chris Mason <clm@fb.com>, Josef Bacik <josef@toxicpanda.com>,
	David Sterba <dsterba@suse.com>,
	linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org,
	yuanxzhang@fudan.edu.cn, kjlu@umn.edu,
	Xin Tan <tanxin.ctf@gmail.com>
Subject: Re: [PATCH] btrfs: Fix btrfs_block_group refcnt leak
Date: Tue, 21 Apr 2020 00:43:15 +0200	[thread overview]
Message-ID: <20200420224315.GI18421@twin.jikos.cz> (raw)
In-Reply-To: <1587361120-83160-1-git-send-email-xiyuyang19@fudan.edu.cn>

On Mon, Apr 20, 2020 at 01:38:40PM +0800, Xiyu Yang wrote:
> btrfs_remove_block_group() invokes btrfs_lookup_block_group(), which
> returns a local reference of the blcok group that contains the given
> bytenr to "block_group" with increased refcount.
> 
> When btrfs_remove_block_group() returns, "block_group" becomes invalid,
> so the refcount should be decreased to keep refcount balanced.
> 
> The reference counting issue happens in several exception handling paths
> of btrfs_remove_block_group(). When those error scenarios occur such as
> btrfs_alloc_path() returns NULL, the function forgets to decrease its
> refcnt increased by btrfs_lookup_block_group() and will cause a refcnt
> leak.
> 
> Fix this issue by jumping to "out_put_group" label and calling
> btrfs_put_block_group() when those error scenarios occur.
> 
> Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
> Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>

Thanks for the fix. May I ask if this was found by code inspection or by
some analysis tool?

> @@ -1132,6 +1132,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
>  		btrfs_delayed_refs_rsv_release(fs_info, 1);
>  	btrfs_free_path(path);
>  	return ret;
> +out_put_group:
> +	btrfs_put_block_group(block_group);
> +	goto out;

As Filipe noted, the trailing gotos are not a great pattern, what we'd
like to do is a more linear sequence where the resource
allocation/freeing nesting is obvious, like:


	x = allocate(X);
	if (!x)
		goto out;
	...
	y = allocate(Y);
	if (!y)
		goto out_free_x;
	z = allocate(Z);
	if (!z)
		goto out_free_y;
	...
	free(z);
out_free_y:
	free(y);
out_free_x:
	free(x);
out:
	return;


(where allocate/free can be refcount inc/dec and similar). Sometimes
it's not that straightforward and the freeing block needs conditionals,
but from code reading perspective this is still better than potentially
wild gotos.

  parent reply	other threads:[~2020-04-20 22:44 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-20  5:38 Xiyu Yang
2020-04-20 17:31 ` Filipe Manana
2020-04-20 22:43 ` David Sterba [this message]
2020-04-21  9:53   ` Xiyu Yang

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=20200420224315.GI18421@twin.jikos.cz \
    --to=dsterba@suse.cz \
    --cc=clm@fb.com \
    --cc=dsterba@suse.com \
    --cc=josef@toxicpanda.com \
    --cc=kjlu@umn.edu \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tanxin.ctf@gmail.com \
    --cc=xiyuyang19@fudan.edu.cn \
    --cc=yuanxzhang@fudan.edu.cn \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®