CVE-2026-93800: btrfs: fix use-after-free on reloc root after error in insert_dirty_subvol()

Published Sep 24, 2026
·
Updated

In the Linux kernel, the following vulnerability has been resolved:

btrfs: fix use-after-free on reloc root after error in insertdirtysubvol()

If during relocation we fail in insertdirtysubvol() because btrfsupdaterelocroot() returned an error, we will leave a root's relocroot field pointing to a reloc root that was freed instead of NULL, resulting later in a use-after-free, or double free attempt during unmount.

The sequence of steps is this:

1) During relocation the call to btrfsupdaterelocroot() in insertdirtysubvol() fails, so insertdirtysubvol() returns the error to mergerelocroot() without adding the root to the list rc->dirtysubvolroots;

2) Then mergerelocroot() aborts the current transaction because insertdirtysubvol() returned an error;

3) Up the call chain, mergerelocroots() gets the error, adds the reloc root for root X to the local relocroots list and jumps to the 'out' label, where it calls freerelocroots() to free all the reloc roots in the local relocroots list. This frees the reloc root for root X;

4) We go up the call chain to relocateblockgroup() which calls cleandirtysubvols() to go over dirty roots and set their ->relocroot field to NULL, but root X is not in the dirtysubvolroots list, so its ->relocroot still points to a reloc root;

5) Relocation finishes, with an error and a transaction abort, but the ->relocroot field for root X still points to the reloc root that was freed in step 3;

6) When unmounting the fs we end up calling:

btrfsfreefsroots() btrfsdropandfreefsroot() --> calls btrfsputroot() against root X's ->relocroot which is not NULL and points to the already freed reloc root in step 4 above

Resulting in a use-after-free to a double free attempt.

Syzbot reported this with the following dmesg/syslog:

[ 106.004389][ T5339] BTRFS error (device loop0 state A): Transaction aborted (error -5) [ 106.014266][ T5339] BTRFS: error (device loop0 state A) in mergerelocroot:1655: errno=-5 IO failure [ 106.021891][ T1061] BTRFS error (device loop0 state A): error while writing out transaction: -5 [ 106.026964][ T1061] BTRFS warning (device loop0 state A): Skipping commit of aborted transaction. [ 106.033807][ T5340] BTRFS error (device loop0 state A): bdev /dev/loop0 errs: wr 3, rd 0, flush 0, corrupt 0, gen 0 [ 106.039265][ T1061] BTRFS: error (device loop0 state A) in cleanuptransaction:2067: errno=-5 IO failure [ 106.044382][ T5339] BTRFS info (device loop0 state EA): forced readonly [ 106.074329][ T5339] BTRFS: error (device loop0 state EA) in mergerelocroots:1887: errno=-5 IO failure [ 106.081004][ T5356] BTRFS info (device loop0 state EA): scrub: started on devid 1 [ 106.085611][ T5339] BTRFS info (device loop0 state EA): balance: ended with status: -30 [ 106.089517][ T5356] BTRFS info (device loop0 state EA): scrub: not finished on devid 1 with status: -30 [ 106.662365][ T5338] BTRFS info (device loop0 state EA): last unmount of filesystem 3a375e4e-b156-4d76-a2ad-16e198ce1409 [ 106.682946][ T5338] ================================================================== [ 106.686574][ T5338] BUG: KASAN: slab-use-after-free in btrfsputroot+0x2f/0x250 [ 106.690090][ T5338] Write of size 4 at addr ffff88803f978630 by task syz.0.0/5338 [ 106.693173][ T5338] [ 106.694279][ T5338] CPU: 0 UID: 0 PID: 5338 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full) [ 106.694293][ T5338] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 106.694300][ T5338] Call Trace: [ 106.694308][ T5338] <TASK> [ 106.694314][ T5338] dumpstacklvl+0xe8/0x150 [ 106.694331][ T5338] printaddressdescription+0x55/0x1e0 [ 106.694343][ T5338] ? btrfsputroot+0x2f/0x250 [ 106.694358][ T5338] printreport+0x58/0x70 [ 106. ---truncated---

Affected Software

1 affected component
Linux Linux kernel

Event History

Sep 24, 2026
CVE Published
via MITRE·04:02 PM
Data Sourced
via MITRE·04:02 PM
Description
Data Sourced
via NVD·05:17 PM
Description

Frequently Asked Questions

1

What conditions are required to reach the vulnerable state?

The issue occurs during Btrfs relocation when insert_dirty_subvol() fails because btrfs_update_reloc_root() returns an error. That failure can leave a root's reloc_root field referring to a relocation root that has already been freed.

2

What can happen after the relocation error?

Later handling can dereference the stale reloc_root pointer, causing a use-after-free. Unmount handling can also attempt to free the same relocation root again, causing a double-free attempt.

3

Can I determine whether my kernel is affected from the supplied version information?

No affected or fixed kernel version ranges are provided. The available references identify three stable-kernel commits associated with the resolved issue.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203