In the Linux kernel, the following vulnerability has been resolved:
btrfs: free exchange changeset on failures
Fstests runs on my VMs have show several kmemleak reports like the following.
unreferenced object 0xffff88811ae59080 (size 64): comm "xfsio", pid 12124, jiffies 4294987392 (age 6.368s) hex dump (first 32 bytes): 00 c0 1c 00 00 00 00 00 ff cf 1c 00 00 00 00 00 ................ 90 97 e5 1a 81 88 ff ff 90 97 e5 1a 81 88 ff ff ................ backtrace: [<00000000ac0176d2>] ulistaddmerge+0x60/0x150 [btrfs] [<0000000076e9f312>] setstatebits+0x86/0xc0 [btrfs] [<0000000014fe73d6>] setextentbit+0x270/0x690 [btrfs] [<000000004f675208>] setrecordextentbits+0x19/0x20 [btrfs] [<00000000b96137b1>] qgroupreservedata+0x274/0x310 [btrfs] [<0000000057e9dcbb>] btrfscheckdatafreespace+0x5c/0xa0 [btrfs] [<0000000019c4511d>] btrfsdelallocreservespace+0x1b/0xa0 [btrfs] [<000000006d37e007>] btrfsdioiomapbegin+0x415/0x970 [btrfs] [<00000000fb8a74b8>] iomapiter+0x161/0x1e0 [<0000000071dff6ff>] _iomapdiorw+0x1df/0x700 [<000000002567ba53>] iomapdiorw+0x5/0x20 [<0000000072e555f8>] btrfsfilewriteiter+0x290/0x530 [btrfs] [<000000005eb3d845>] newsyncwrite+0x106/0x180 [<000000003fb505bf>] vfswrite+0x24d/0x2f0 [<000000009bb57d37>] _x64syspwrite64+0x69/0xa0 [<000000003eba3fdf>] dosyscall_64+0x43/0x90
In case brtfsqgroupreservedata() or btrfsdelallocreservemetadata() fail the allocated extent_changeset will not be freed.
So in btrfscheckdatafreespace() and btrfsdelallocreservespace() free the allocated extentchangeset to get rid of the allocated memory.
The issue currently only happens in the direct IO write path, but only after 65b3c08606e5 ("btrfs: fix ENOSPC failure when attempting direct IO write into NOCOW range"), and also at defragonelockedtarget(). Every other place is always calling extentchangesetfree() even if its call to btrfsdelallocreservespace() or btrfscheckdatafreespace() has failed.