In the Linux kernel, the following vulnerability has been resolved:
ext4: fix slab-use-after-free in ext4splitextent_at()
We hit the following use-after-free:
================================================================== BUG: KASAN: slab-use-after-free in ext4splitextentat+0xba8/0xcc0 Read of size 2 at addr ffff88810548ed08 by task kworker/u20:0/40 CPU: 0 PID: 40 Comm: kworker/u20:0 Not tainted 6.9.0-dirty #724 Call Trace: <TASK> kasanreport+0x93/0xc0 ext4splitextentat+0xba8/0xcc0 ext4splitextent.isra.0+0x18f/0x500 ext4splitconvertextents+0x275/0x750 ext4exthandleunwrittenextents+0x73e/0x1580 ext4extmapblocks+0xe20/0x2dc0 ext4mapblocks+0x724/0x1700 ext4do_writepages+0x12d6/0x2a70 [...]
Allocated by task 40: _kmallocnoprof+0x1ac/0x480 ext4findextent+0xf3b/0x1e70 ext4extmapblocks+0x188/0x2dc0 ext4mapblocks+0x724/0x1700 ext4do_writepages+0x12d6/0x2a70 [...]
Freed by task 40: kfree+0xf1/0x2b0 ext4findextent+0xa71/0x1e70 ext4extinsertextent+0xa22/0x3260 ext4splitextentat+0x3ef/0xcc0 ext4splitextent.isra.0+0x18f/0x500 ext4splitconvertextents+0x275/0x750 ext4exthandleunwrittenextents+0x73e/0x1580 ext4extmapblocks+0xe20/0x2dc0 ext4mapblocks+0x724/0x1700 ext4dowritepages+0x12d6/0x2a70
The flow of issue triggering is as follows:
ext4splitextentat path = *ppath ext4extinsertextent(ppath) ext4extcreatenewleaf(ppath) ext4findextent(origpath) path = *origpath readextenttreeblock // return -ENOMEM or -EIO ext4freeextpath(path) kfree(path) *origpath = NULL a. If err is -ENOMEM: ext4extdirty(path + path->pdepth) // path use-after-free !!! b. If err is -EIO and we have EXTDEBUG defined: ext4extshowleaf(path) eh = path[depth].p_hdr // path also use-after-free !!!
So when trying to zeroout or fix the extent length, call ext4findextent() to update the path.
In addition we use *ppath directly as an ext4extshowleaf() input to avoid possible use-after-free when EXTDEBUG is defined, and to avoid unnecessary path updates.