CVE-2026-90264: btrfs: always wait for ordered extents to avoid OE races
In the Linux kernel, the following vulnerability has been resolved:
btrfs: always wait for ordered extents to avoid OE races
[BUG] Syzbot reported a bug that there can be conflicting OEs for the same range:
BTRFS critical (device loop4): panic in insertorderedextent:264: overlapping ordered extents, existing oe fileoffset 16384 numbytes 430080 flags 0x1089, new oe fileoffset 16384 numbytes 430080 flags 0x80 (errno=-17 Object alrea[ 179.162726][ T6897] BTRFS critical (device loop4): panic in insertorderedextent:264: overlapping ordered extents, existing oe fileoffset 16384 numbytes 430080 flags 0x1089, new oe fileoffset 16384 numbytes 430080 flags 0x80 (errno=-17 Object already exists) ------------[ cut here ]------------ kernel BUG at fs/btrfs/ordered-data.c:264! Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/09/2026 RIP: 0010:btrfsallocorderedextent+0x943/0xad0 Call Trace: <TASK> cowfilerange+0x744/0x12a0 fallbacktocow+0x5ea/0xa00 rundelallocnocow+0x110c/0x17a0 btrfsrundelallocrange+0xbe4/0x1c20 writepagedelalloc+0x104d/0x1ba0 btrfswritepages+0x1667/0x28b0 dowritepages+0x338/0x560 filemapfdatawriterange+0x1f2/0x300 btrfsfdatawriterange+0x54/0xf0 btrfsdirectwrite+0x6a0/0xc30 btrfsdowriteiter+0x329/0x790 doiterreadvwritev+0x624/0x8d0 vfswritev+0x34c/0x990 sesyspwritev2+0x17a/0x2a0 dosyscall64+0x174/0x580 entrySYSCALL64afterhwframe+0x77/0x7f </TASK> ---[ end trace 0000000000000000 ]---
[CAUSE] Since commit ff66fe666233 ("btrfs: fix incorrect buffered IO fallback for append direct writes"), if the direct IO finished short, we will revert the isize back to the original one, so that append writes can be respected during the buffered fallback.
Normally we rely on lockandcleanupextentifneed() function during buffered writeback to wait for any existing ordered extents.
But that ordered extent waiting only happens if the startpos is inside the isize. Since we have reverted the isize during failed direct IO, we will not wait for any ordered extents.
This means we can have a race where the direct IO OE is still in the tree, finished but not yet removed, then we're inserting the OE for the buffered write, causing the above crash.
[FIX] Make the OE wait to be unconditional, to handle the reverted isize situation.
And since lockandcleanupextentifneed() now either lock the extents or return -EAGAIN, also remove the branches that handles no-extent-locked cases, and rename it to remove the "ifneed" suffix.
The following micro benchmark shows the runtime difference for btrfsbufferedwrite(), doing xfsio -f -c "pwrite 0 1m" workload, all values are the average runtime in nano seconds.
function runtime | before | after -----------------------------------+-------------+--------------- lockandcleanupextentifneed() | 58.2 | 183.0 btrfsbufferedwrite() | 2115.6 | 2973.3
The overall runtime of btrfsbufferedwrite() is still pretty tiny (still less than 3 micro seconds), I'd say the extra cost is still acceptable.
An alternative to fix this problem is to wait ordered extents during iomapend() where the isize revert is done.
But that solution will break nowait requirement, as if a nowait direct IO finished short, we have to wait for the OEs unconditionally or the next append buffered IO can still hit the same problem.
So here we have to move the wait cost to buffered write, but at least the code is slightly more streamline.
Affected Software
Event History
Frequently Asked Questions
What impact is documented for affected systems?
The reported failure triggers a kernel BUG and Btrfs critical messages when overlapping ordered extents are inserted for the same file range. This can panic the kernel.
How can administrators identify that this issue has occurred?
Check kernel logs for BTRFS critical messages mentioning "overlapping ordered extents" and a panic in insert_ordered_extent or btrfs_alloc_ordered_extent. The example reports errno -17, "Object already exists," for conflicting extents with identical file offsets and byte ranges.
Does the report describe attacker access or a remote exploitation path?
No. The provided information describes a Syzbot-reported ordered-extent race and resulting kernel panic, but does not specify an attacker model, required access level, or remote attack path.