CVE-2026-90301: ocfs2: o2hb: quiesce negotiate handlers and timeout work
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: o2hb: quiesce negotiate handlers and timeout work
Heartbeat regions publish struct o2hbregion as the private data for the NEGOTIMEOUT and NEGOAPPROVE o2net handlers as soon as makeitem() creates the configfs region. The approve handler can call o2hbarmtimeout(), so a peer can touch the region timeout work before devstore() has finished building the heartbeat runtime, or after teardown has started to shut that runtime back down.
The final configfs put also has to keep reg alive until the last in-flight o2net callback drops its handler reference. o2netunregisterhandlerlist() blocks future handler lookups, but it does not wait for scrxwork that already passed o2nethandlerget(). That drain needs to cover local listener teardown as well, where the o2net ordered workqueue may already be inside destroyworkqueue().
Fix the lifetime rule in both directions. Initialize the region delayed works before publishing reg through the o2net handler table, keep new or stopping regions non-armable with hrstopping, and quiesce both delayed works on failed-start and teardown paths even when no heartbeat thread is left to call o2hbdisarmtimeout(). Then unregister handlers before tearing down handler-visible region state and make the drain wait for the active or destroying o2net ordered workqueue before release frees reg.
The buggy scenario involves two paths, with each column showing the order within that path:
region lifecycle: late negotiate callback: 1. makeitem() registers the 1. o2netprocessmessage() gets a region handlers before heartbeat handler for reg. devstore() has built a 2. The callback runs after the lookup runnable heartbeat context. lock is dropped and dereferences reg. 2. A failed start or rmdir 3. An approve or timeout path tries to stops the heartbeat thread, queue reg's delayed work, or release quiesces existing work, and races the callback body after handler drops the final configfs ref. unregister. 3. regionrelease() must drain 4. The callback or delayed work can handler-visible o2net rx work outlive reg unless lifecycle code before freeing reg. keeps the region non-armable and drains the active-or-destroying o2net workqueue.
Validation reproduced this kernel report: KASAN slab-use-after-free in runtimers+0x22c/0x5b0 Write of size 8 Call trace: dumpstacklvl+0x66/0xa0 printreport+0xce/0x630 runtimers+0x22c/0x5b0 kasanreport+0xe0/0x110 rawspinunlockirqrestore+0x27/0x60 trytowakeup+0x191/0xf70 timerexpireremote+0xae/0xf0 runtimersoftirq+0x19b/0x1a0 handlesoftirqs+0x156/0x660 irqexitrcu+0xc4/0x160 irqexitrcu+0xe/0x20 sysvecapictimerinterrupt+0x6c/0x80 asmsysvecapictimerinterrupt+0x1a/0x20
Allocated by task stack: kasansavestack+0x33/0x60 kasansavetrack+0x14/0x30 kasankmalloc+0xaa/0xb0 o2hbheartbeatgroupmakeitem+0x3c/0x600
Affected Software
Event History
Frequently Asked Questions
Who can trigger the vulnerable code path?
A peer that can send o2net NEGO_TIMEOUT or NEGO_APPROVE traffic can reach the affected handlers. The issue is tied to OCFS2 heartbeat regions and their interaction with o2net callbacks.
When is exploitation most likely to occur?
The race exists while a heartbeat region is being initialized before dev_store() finishes building its runtime, and while the region is being torn down. An in-flight o2net callback that obtained a handler reference before handler unregistration can still access the region during teardown.
Does unregistering the o2net handlers alone prevent the issue?
No. Handler unregistration prevents future lookups but does not wait for receive work that already acquired a handler reference. The affected lifetime handling must also keep the region alive until those callbacks finish and quiesce the delayed timeout-related work.