CVE-2026-89491
NoneCVSS
—
EPSS
0.2%
Published
Sep 11, 2026
CISA due date
—
Cloudanix analysis
A bug in Linux clustered storage can freeze or crash a server when it joins or reconfigures shared disks, interrupting access to those files.
- Exploitation
- Local Privilege
- Attacker needs
- Local User
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- OS kernel
- Class
- Race Condition
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
OCFS2 cluster heartbeat pinning holds the o2hb_live_lock spinlock while calling configfs_depend_item(), which sleeps (filesystem pin plus configfs root inode rwsem). That violates atomic context and can BUG the kernel under CONFIG_DEBUG_ATOMIC_SLEEP. The same path can deadlock via inode_lock versus configfs-root lock inversion when invoked from a configfs drop_item callback, and a partial failure in o2hb_region_inc_user() leaks o2hb_dependent_users so regions stay inconsistently pinned and subsequent mounts may run without expected heartbeat protection.
Why it matters to the business
Linux hosts using OCFS2 shared storage can panic, deadlock, or join the cluster with heartbeat in an inconsistent state during mount or heartbeat reconfiguration, causing node outages, failed cluster membership, and weaker node-failure detection. Public exploit activity is not reported, EPSS remains very low and stable, and the issue is not in KEV, so urgency is availability-driven for clustered storage rather than mass remote compromise.
How an attack unfolds
A local actor (or even a legitimate mount/reconfigure) on a system with OCFS2 cluster heartbeat triggers o2hb_register_callback / o2hb_region_inc_user while o2hb_live_lock is held. o2hb_region_pin() then sleeps in configfs_depend_item(), producing an atomic-sleep BUG or a lock-order deadlock against configfs unregistration. Forcing a mid-sequence pin failure leaks the dependent-user counter so heartbeat regions are not fully released, leaving later mounts without the intended heartbeat coverage and enabling cluster disruption through node hang, panic, or unprotected heartbeat rather than remote code execution.
How to fix it
Upgrade to a vendor or upstream Linux kernel that includes the OCFS2 o2hb_region_pin() series: drop o2hb_live_lock across each sleeping configfs_depend_item() while holding a config_item reference, use configfs_depend_item_unlocked() when called from configfs drop_item, and unpin plus decrement o2hb_dependent_users on partial failure in o2hb_region_inc_user(). Prefer a full kernel package update over cherry-picks. Until patched, avoid mounting or reconfiguring OCFS2 heartbeat regions on affected kernels and limit who can perform those operations.
How to confirm the fix worked
Confirm the running kernel changelog or patch list includes the o2hb_region_pin lock-drop, unlocked-depend-from-callback, and o2hb_region_inc_user error-path unpin fixes. After update, mount OCFS2 and register DLM domains with CONFIG_DEBUG_ATOMIC_SLEEP enabled in a test environment and verify no atomic-sleep BUG in o2hb_region_pin. Exercise heartbeat group drop_item and failed-pin paths and confirm o2hb_dependent_users does not remain elevated and regions are not left pinned.
Typical attack path
- Obtain local access on a Linux system where OCFS2 cluster heartbeat is available
- Trigger heartbeat region pin via OCFS2 mount, DLM domain registration, or configfs heartbeat item drop
- Cause o2hb_region_pin() to sleep under o2hb_live_lock or invert parent versus configfs-root inode locks
- Optionally abort pin mid-way so o2hb_dependent_users leaks and regions stay inconsistently pinned
- Induce kernel BUG, deadlock, or unprotected heartbeat, disrupting clustered storage availability
How to detect it
This is a local kernel correctness and deadlock issue, not a network worm. Hunt kernel logs and crash dumps around OCFS2 mount, DLM init, and heartbeat configfs changes for atomic-sleep BUGs, lockdep inversions, and hung tasks. Sources: dmesg, journalctl -k, /var/log/kern.log, /var/log/messages, kdump/vmcore, lockdep reports. Stack frames of interest include o2hb_region_pin, o2hb_region_inc_user, o2hb_register_callback, configfs_depend_item, ocfs2_dlm_init, ocfs2_mount_volume, ocfs2_fill_super, and process name mount.ocfs2. Correlate with cluster fencing, membership flaps, and failed OCFS2 mounts. No named threat actors or public exploit tooling are associated.
- BUG: sleeping function called from invalid context at kernel/locking/rwsem.c
- in_atomic(): 1
- name: mount.ocfs2
- o2hb_region_pin
- o2hb_region_inc_user
- o2hb_register_callback
- o2hb_heartbeat_group_drop_item
- configfs_depend_item
- o2nm_depend_item
- dlm_register_domain_handlers
- ocfs2_dlm_init
- ocfs2_mount_volume
- ocfs2_fill_super
- possible deadlock
- configfs
What your security team should do
- Inventory nodes that mount OCFS2 or load ocfs2/o2hb cluster heartbeat and patch those kernels first
- Track distribution kernel advisories for the o2hb_region_pin series and deploy the updated kernel package
- Until patched, restrict mount and configfs heartbeat reconfiguration to trusted cluster admins
- Alert on kernel atomic-sleep BUGs and lockdep traces involving o2hb_region_pin, configfs_depend_item, and mount.ocfs2
- Treat this as cluster-availability hygiene: low EPSS, no KEV, no known in-the-wild exploitation
The record
In the Linux kernel, the following vulnerability has been resolved: ocfs2: cluster: don't sleep while holding o2hb_live_lock in o2hb_region_pin() Patch series "ocfs2: cluster: o2hb_region_pin() fixes", v2. This series fixes three related issues in o2hb_region_pin(), all are from the original implementation in commit: 58a3158a5d17 ("ocfs2/cluster: Pin/unpin o2hb regions"): 1) It is called with o2hb_live_lock (a spinlock) held, but the underlying configfs_depend_item() sleeps (takes inode rwsem and pins the filesystem). This triggers BUG under CONFIG_DEBUG_ATOMIC_SLEEP. 2) When called from the configfs drop_item callback, it creates a lock order inversion: parent inode_lock -> configfs root inode_lock, which can deadlock against subsystem unregistration paths taking root -> parent. 3) If pinning fails partway through o2hb_region_inc_user(), the o2hb_dependent_users counter is leaked and partially-pinned regions are never released, leaving heartbeat regions unprotected on subsequent mounts. Patch 1 reworks o2hb_region_pin() to drop o2hb_live_lock across each sleeping configfs_depend_item() call, using a config_item reference to keep the region alive while unlocked. Patch 2 adds a from_callback parameter to select configfs_depend_item_unlocked() when called from configfs context, avoiding the inode_lock nesting. Patch 3 fixes the error path in o2hb_region_inc_user() to unpin and decrement the counter on failure. This patch (of 3): o2hb_region_pin() is always called with the o2hb_live_lock spinlock held (from o2hb_region_inc_user() and o2hb_heartbeat_group_drop_item()), but it calls o2nm_depend_item() -> configfs_depend_item(), which sleeps: it pins the configfs filesystem and takes the configfs root inode rwsem. Under CONFIG_DEBUG_ATOMIC_SLEEP this triggers: BUG: sleeping function called from invalid context at kernel/locking/rwsem.c in_atomic(): 1, ... name: mount.ocfs2 down_write configfs_depend_item o2hb_region_pin o2hb_region_inc_user o2hb_register_callback dlm_register_domain_handlers ... ocfs2_dlm_init ocfs2_mount_volume ocfs2_fill_super Rework o2hb_region_pin() to pin one region at a time with the lock dropped across the sleeping call: under o2hb_live_lock find the next eligible region and take a config_item reference to keep it alive, drop the lock, call o2nm_depend_item(), then retake the lock and record the pin. The config_item_put() is done with the lock released as well, since o2hb_region_release() also acquires o2hb_live_lock and can sleep. The region list may change while unlocked, so the scan restarts from the top after each pin. Local heartbeat still pins only the matching region; global heartbeat pins all eligible regions. The unpin path is unaffected: configfs_undepend_item() only takes a spinlock and does not sleep.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|