All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leo Martins <loemra.dev@gmail.com>
To: Filipe Manana <fdmanana@kernel.org>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com,
	kernel test robot <oliver.sang@intel.com>
Subject: Re: [PATCH v2] btrfs: fix use-after-free warning in btrfs_get_or_create_delayed_node
Date: Fri, 12 Dec 2025 17:28:21 -0800	[thread overview]
Message-ID: <20251213012829.89988-1-loemra.dev@gmail.com> (raw)
In-Reply-To: <CAL3q7H7h0=3ombZ9L0L++RHhTfymEKroTVFvW33eRb9ZjWAWKA@mail.gmail.com>

On Fri, 12 Dec 2025 09:32:06 +0000 Filipe Manana <fdmanana@kernel.org> wrote:

> On Fri, Dec 12, 2025 at 1:01 AM Leo Martins <loemra.dev@gmail.com> wrote:
> >
> > On Wed, 3 Dec 2025 10:50:17 +0000 Filipe Manana <fdmanana@kernel.org> wrote:
> >
> > > On Tue, Dec 2, 2025 at 9:21 PM Leo Martins <loemra.dev@gmail.com> wrote:
> > > >
> > > > Previously, btrfs_get_or_create_delayed_node sets the delayed_node's
> > > > refcount before acquiring the root->delayed_nodes lock.
> > > > Commit e8513c012de7 ("btrfs: implement ref_tracker for delayed_nodes")
> > > > moves refcount_set inside the critical section which means
> > > > there is no longer a memory barrier between setting the refcount and
> > > > setting btrfs_inode->delayed_node = node.
> > > >
> > > > This allows btrfs_get_or_create_delayed_node to set
> > > > btrfs_inode->delayed_node before setting the refcount.
> > > > A different thread is then able to read and increase the refcount
> > > > of btrfs_inode->delayed_node leading to a refcounting bug and
> > > > a use-after-free warning.
> > > >
> > > > The fix is to move refcount_set back to where it was to take
> > > > advantage of the implicit memory barrier provided by lock
> > > > acquisition.
> > > >
> > > > Fixes: e8513c012de7 ("btrfs: implement ref_tracker for delayed_nodes")
> > > > Reported-by: kernel test robot <oliver.sang@intel.com>
> > > > Closes: https://lore.kernel.org/oe-lkp/202511262228.6dda231e-lkp@intel.com
> > > > Tested-by: kernel test robot <oliver.sang@intel.com>
> > > > Signed-off-by: Leo Martins <loemra.dev@gmail.com>
> > > > ---
> > > >  fs/btrfs/delayed-inode.c | 32 +++++++++++++++++---------------
> > > >  1 file changed, 17 insertions(+), 15 deletions(-)
> > > >
> > > > diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
> > > > index 364814642a91..81922556379d 100644
> > > > --- a/fs/btrfs/delayed-inode.c
> > > > +++ b/fs/btrfs/delayed-inode.c
> > > > @@ -152,37 +152,39 @@ static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node(
> > > >                 return ERR_PTR(-ENOMEM);
> > > >         btrfs_init_delayed_node(node, root, ino);
> > > >
> > > > +       /* Cached in the inode and can be accessed. */
> > > > +       refcount_set(&node->refs, 2);
> > > > +       btrfs_delayed_node_ref_tracker_alloc(node, tracker, GFP_ATOMIC);
> > > > +       btrfs_delayed_node_ref_tracker_alloc(node, &node->inode_cache_tracker, GFP_ATOMIC);
> > >
> > > Now that we do these allocations outside the spinlock (xarray's lock),
> > > we can stop using GFP_ATOMIC and use GFP_NOFS.
> > >
> > > Otherwise it looks good, thanks.
> >
> > Did you want me to send out a v3 for this change?
> 
> You can make it either in a v3 or as a separate patch, I don't have a
> strong preference for this.
> 
> Either way:
> 
> Reviewed-by: Filipe Manana <fdmanana@suse.com>
> 
> (Applies both to this, a possible v3 and a standalone patch for
> replacing GFP_ATOMIC with GFP_NOFS).
> 
> If you can't push to for-next, let me know and I can do it.

Just sent out a v3. I can't push to for-next, if you could that
would be great.

Thanks.

> 
> Thanks.
> 
> >
> > >
> > > > +
> > > >         /* Allocate and reserve the slot, from now it can return a NULL from xa_load(). */
> > > >         ret = xa_reserve(&root->delayed_nodes, ino, GFP_NOFS);
> > > > -       if (ret == -ENOMEM) {
> > > > -               btrfs_delayed_node_ref_tracker_dir_exit(node);
> > > > -               kmem_cache_free(delayed_node_cache, node);
> > > > -               return ERR_PTR(-ENOMEM);
> > > > -       }
> > > > +       if (ret == -ENOMEM)
> > > > +               goto cleanup;
> > > > +
> > > >         xa_lock(&root->delayed_nodes);
> > > >         ptr = xa_load(&root->delayed_nodes, ino);
> > > >         if (ptr) {
> > > >                 /* Somebody inserted it, go back and read it. */
> > > >                 xa_unlock(&root->delayed_nodes);
> > > > -               btrfs_delayed_node_ref_tracker_dir_exit(node);
> > > > -               kmem_cache_free(delayed_node_cache, node);
> > > > -               node = NULL;
> > > > -               goto again;
> > > > +               goto cleanup;
> > > >         }
> > > >         ptr = __xa_store(&root->delayed_nodes, ino, node, GFP_ATOMIC);
> > > >         ASSERT(xa_err(ptr) != -EINVAL);
> > > >         ASSERT(xa_err(ptr) != -ENOMEM);
> > > >         ASSERT(ptr == NULL);
> > > > -
> > > > -       /* Cached in the inode and can be accessed. */
> > > > -       refcount_set(&node->refs, 2);
> > > > -       btrfs_delayed_node_ref_tracker_alloc(node, tracker, GFP_ATOMIC);
> > > > -       btrfs_delayed_node_ref_tracker_alloc(node, &node->inode_cache_tracker, GFP_ATOMIC);
> > > > -
> > > >         btrfs_inode->delayed_node = node;
> > > >         xa_unlock(&root->delayed_nodes);
> > > >
> > > >         return node;
> > > > +cleanup:
> > > > +       btrfs_delayed_node_ref_tracker_free(node, tracker);
> > > > +       btrfs_delayed_node_ref_tracker_free(node, &node->inode_cache_tracker);
> > > > +       btrfs_delayed_node_ref_tracker_dir_exit(node);
> > > > +       kmem_cache_free(delayed_node_cache, node);
> > > > +       if (ret)
> > > > +               return ERR_PTR(ret);
> > > > +       goto again;
> > > >  }
> > > >
> > > >  /*
> > > > --
> > > > 2.47.3
> > > >
> > > >

Sent using hkml (https://github.com/sjp38/hackermail)

      reply	other threads:[~2025-12-13  1:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-02 21:21 [PATCH v2] btrfs: fix use-after-free warning in btrfs_get_or_create_delayed_node Leo Martins
2025-12-03 10:50 ` Filipe Manana
2025-12-12  1:01   ` Leo Martins
2025-12-12  9:32     ` Filipe Manana
2025-12-13  1:28       ` Leo Martins [this message]

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=20251213012829.89988-1-loemra.dev@gmail.com \
    --to=loemra.dev@gmail.com \
    --cc=fdmanana@kernel.org \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=oliver.sang@intel.com \
    /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.