CVE-2026-89645: btrfs: drop recovered reloc root refs on recovery failure
In the Linux kernel, the following vulnerability has been resolved:
btrfs: drop recovered reloc root refs on recovery failure
During relocation recovery, each fs root gets a reference to its relocation root. If loading or adding a later root fails, or if the first transaction commit fails, btrfsrecoverrelocation() jumps to outunset before mergerelocroots() and cleandirtysubvols().
putreloccontrol() drops the list-owned relocation root references, but it does not clear fsroot->relocroot or drop the references owned by those pointers. Mount cleanup only drops them when BTRFSFSERROR is set, so an error such as -ENOMEM while processing a later root can leave references behind.
Keep temporary references to the fs roots associated during recovery. On failure, clear their relocroot pointers and drop the corresponding references. Once the first transaction commit succeeds, drop only the temporary fs root references and let the normal merge and cleanup paths handle the relocation roots.
Fault injection on a pending-relocation image confirmed the cleanup gap. With an injected first-commit failure, 25 fs roots had relocroot set with fserror=0. With this fix, the same failure path drops that count to 0 before mount fails.
Affected Software
Event History
Frequently Asked Questions
When can this issue be triggered?
It occurs during Btrfs relocation recovery when processing a pending-relocation filesystem image. A failure while loading or adding a later filesystem root, or failure of the first transaction commit, can leave relocation-root references behind.
What conditions make an affected system more likely to encounter the problem?
The described failure paths include an out-of-memory error while processing a later root and an injected failure of the first transaction commit. The issue depends on relocation recovery and an error occurring before relocation roots are merged and dirty subvolumes are cleaned.
How can the affected state be identified?
In the demonstrated first-commit failure case, filesystem roots retained reloc_root pointers while BTRFS_FS_ERROR remained unset. The fault-injection test observed 25 such roots on a pending-relocation image before the fix.
What does the fix change?
On recovery failure, the fix clears the reloc_root pointers for roots associated during recovery and drops their corresponding references. After the first transaction commit succeeds, it drops only temporary filesystem-root references and leaves normal merge and cleanup paths to handle relocation roots.