]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
btrfs: fix use-after-free warning in btrfs_get_or_create_delayed_node()
authorLeo Martins <loemra.dev@gmail.com>
Sat, 13 Dec 2025 01:26:26 +0000 (17:26 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 17 Jan 2026 15:35:18 +0000 (16:35 +0100)
commitc8385851a5435f4006281828d428e5d0b0bbf8af
tree4c7308c808c67c37b397d21ba062271ecfca3c9d
parent99e057f3d3ef24b99a7b1d84e01dd1bd890098da
btrfs: fix use-after-free warning in btrfs_get_or_create_delayed_node()

[ Upstream commit 83f59076a1ae6f5c6845d6f7ed3a1a373d883684 ]

Previously, btrfs_get_or_create_delayed_node() set the delayed_node's
refcount before acquiring the root->delayed_nodes lock.
Commit e8513c012de7 ("btrfs: implement ref_tracker for delayed_nodes")
moved 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.

Without that barrier, the stores to node->refs and
btrfs_inode->delayed_node may become visible out of order. Another
thread can then read btrfs_inode->delayed_node and attempt to
increment a refcount that hasn't been set yet, 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.

Because the allocations now happen outside of the lock's critical
section, they can use GFP_NOFS instead of GFP_ATOMIC.

Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202511262228.6dda231e-lkp@intel.com
Fixes: e8513c012de7 ("btrfs: implement ref_tracker for delayed_nodes")
Tested-by: kernel test robot <oliver.sang@intel.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Leo Martins <loemra.dev@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/btrfs/delayed-inode.c