In the Linux kernel, the following vulnerability has been resolved:
fs: writeback: fix use-after-free in _markinode_dirty()
An use-after-free issue occurred when _markinodedirty() get the bdiwriteback that was in the progress of switching.
CPU: 1 PID: 562 Comm: systemd-random- Not tainted 6.6.56-gb4403bd46a8e #1 ...... pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : _markinodedirty+0x124/0x418 lr : _markinodedirty+0x118/0x418 sp : ffffffc08c9dbbc0 ........ Call trace: _markinodedirty+0x124/0x418 genericupdatetime+0x4c/0x60 filemodified+0xcc/0xd0 ext4bufferedwriteiter+0x58/0x124 ext4filewriteiter+0x54/0x704 vfswrite+0x1c0/0x308 ksyswrite+0x74/0x10c _arm64syswrite+0x1c/0x28 invokesyscall+0x48/0x114 el0svccommon.constprop.0+0xc0/0xe0 doel0svc+0x1c/0x28 el0svc+0x40/0xe4 el0t64synchandler+0x120/0x12c el0t64sync+0x194/0x198
Root cause is:
_markinodedirty inodeswitchwbsworkfn
spinlock(&inode->ilock); inodeattachwb lockedinodetowbandlocklist get inode->iwb spinunlock(&inode->ilock); spinlock(&wb->listlock) spinlock(&inode->ilock) inodeiolistmovelocked spinunlock(&wb->listlock) spinunlock(&inode->ilock) spinlock(&oldwb->listlock) inodedoswitchwbs spinlock(&inode->ilock) inode->iwb = newwb spinunlock(&inode->ilock) spinunlock(&oldwb->listlock) wbputmany(oldwb, nrswitched) cgwbrelease old wb released wbwakeup_delayed() accesses wb, then trigger the use-after-free issue
Fix this race condition by holding inode spinlock until wbwakeupdelayed() finished.