All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leo Martins <loemra.dev@gmail.com>
To: Filipe Manana <fdmanana@kernel.org>
Cc: Oliver Sang <oliver.sang@intel.com>,
	oe-lkp@lists.linux.dev, lkp@intel.com,
	linux-kernel@vger.kernel.org, David Sterba <dsterba@suse.com>,
	linux-btrfs@vger.kernel.org
Subject: Re: [linus:master] [btrfs] e8513c012d: addition_on#;use-after-free
Date: Tue,  2 Dec 2025 13:03:25 -0800	[thread overview]
Message-ID: <20251202210330.2705156-1-loemra.dev@gmail.com> (raw)
In-Reply-To: <CAL3q7H6q-j8Xo_SHGyY0+pHj=BQHezTwxbP9VKQxgLruqxQdow@mail.gmail.com>

On Tue, 2 Dec 2025 19:19:05 +0000 Filipe Manana <fdmanana@kernel.org> wrote:

> On Tue, Dec 2, 2025 at 5:17 PM Leo Martins <loemra.dev@gmail.com> wrote:
> >
> > On Tue, 2 Dec 2025 15:04:51 +0000 Filipe Manana <fdmanana@kernel.org> wrote:
> >
> > > On Tue, Dec 2, 2025 at 8:40 AM Oliver Sang <oliver.sang@intel.com> wrote:
> > > >
> > > > hi, Leo Martins,
> > > >
> > > > On Mon, Dec 01, 2025 at 04:51:41PM -0800, Leo Martins wrote:
> > > >
> > > > [...]
> > > >
> > > > >
> > > > > Hello,
> > > > >
> > > > > I believe I have identified the root cause of the warning.
> > > > > However, I'm having some troubles running the reproducer as I
> > > > > haven't setup lkp-tests yet. Could you test the patch below
> > > > > against your reproducer to see if it fixes the issue?
> > > >
> > > > we confirmed your patch fixed the issues we reported in origial report. thanks!
> > > >
> > > > Tested-by: kernel test robot <oliver.sang@intel.com>
> > > >
> > > > >
> > > > > ---8<---
> > > > >
> > > > > [PATCH] btrfs: fix use-after-free in btrfs_get_or_create_delayed_node
> > > > >
> > > > > 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
> > > > > Signed-off-by: Leo Martins <loemra.dev@gmail.com>
> > > > > ---
> > > > >  fs/btrfs/delayed-inode.c | 34 ++++++++++++++++++----------------
> > > > >  1 file changed, 18 insertions(+), 16 deletions(-)
> > > > >
> > > > > diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
> > > > > index 364814642a91..f61f10000e33 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);
> > > > > +
> > > > >       /* 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;
> > > > > +     WRITE_ONCE(btrfs_inode->delayed_node, node);
> > >
> > > Why the WRITE_ONCE() change?
> >
> > Since there are lockless readers of btrfs_inode->delayed_node all writers
> > should be marked with WRITE_ONCE to force the compiler to store atomically.
> 
> If by atomically you mean to avoid store/load tearing, then using the
> _ONCE() macros won't do anything because we are dealing with pointers.
> This has been discussed in the past, see:
> 
> https://lore.kernel.org/linux-btrfs/cover.1715951291.git.fdmanana@suse.com/

That is what I meant. Missed that discussion, thanks for the link.
I do still see some value in using WRITE_ONCE which is for the human
reader to realize that there are lockless readers, but that's pretty
minor.
> 
> >
> > >
> > > Can you explain in the changelog why it's being introduced?
> > > This seems unrelated and it was not there before the commit mentioned
> > > in the Fixes tag.
> >
> > I'll send out a v2 without the WRITE_ONCE since it is not directly related
> > to this bug and send out a separate patch updating writes to use WRITE_ONCE.
> >
> > Thanks.
> >
> > >
> > > Thanks.
> > >
> > > > >       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
> > > >
> >

  reply	other threads:[~2025-12-02 21:03 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-26 14:23 [linus:master] [btrfs] e8513c012d: addition_on#;use-after-free kernel test robot
2025-12-02  0:51 ` Leo Martins
2025-12-02  8:40   ` Oliver Sang
2025-12-02 15:04     ` Filipe Manana
2025-12-02 17:17       ` Leo Martins
2025-12-02 19:19         ` Filipe Manana
2025-12-02 21:03           ` Leo Martins [this message]
2025-12-03 10:45             ` Filipe Manana
2025-12-02 17:18     ` Leo Martins

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=20251202210330.2705156-1-loemra.dev@gmail.com \
    --to=loemra.dev@gmail.com \
    --cc=dsterba@suse.com \
    --cc=fdmanana@kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=oe-lkp@lists.linux.dev \
    --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.