Cloudanix VulnDB

CVE-2026-89493

High · 8.8

CVSS

8.8

EPSS

0.7%

Published

Sep 11, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A bug in Linux’s clustered disk filesystem can let someone with a malicious disk image crash a server or corrupt its core memory while copying files.

Exploitation
Local Privilege
Attacker needs
High Privilege
Complexity
Moderate
Impact
Full Compromise
Component
OS kernel
Class
Memory Corruption
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

OCFS2 failed to validate on-disk refcount-block fields rl_count and rl_used against the fixed per-block record capacity before walking rf_records. A forged rl_used (for example 0xffff) makes ocfs2_find_refcount_rec_in_rl() index far past the metadata block, then ocfs2_insert_refcount_rec() memmove up to ~1 MiB from an already out-of-bounds address. That is a kernel out-of-bounds read followed by an out-of-bounds write during reflink, CoW, or refcount-increase paths, causing memory corruption, KASAN/oops, panic, or further kernel-memory overwrite.

Why it matters to the business

Hosts that mount OCFS2—typical in clustered shared-disk and Oracle-style Linux storage—can lose the node to a kernel panic or, in the worst case, suffer kernel-level compromise. Impact is concentrated on OCFS2 users rather than the general Linux estate. The issue is not in CISA KEV, has no reported ransomware use, exploit maturity is none, and EPSS is low and flat (~0.65% over 30 days), so mass opportunistic exploitation is unlikely. It has been public for about a month (CVSS 8.8), so unpatched clustered storage nodes remain a high-severity local/cluster risk until kernels are updated.

How an attack unfolds

The attacker needs to present a crafted or corrupted OCFS2 image: mount it with CAP_SYS_ADMIN, write the backing block device of a live OCFS2 volume, or supply a malicious shared volume in a cluster. Existing ECC, signature, block-number, and fs-generation checks are satisfied, but rl_used/rl_count exceed the real array capacity (247 records on a typical 4K block). An ordinary reflink (FICLONE) is issued against an extent whose cpos sorts past every genuine leaf record, so lookup does not return early. The kernel walks off the end of the block and performs an oversized memmove in ocfs2_insert_refcount_rec(), corrupting kernel memory for crash or further privilege. No public exploit, named APT, or unauthenticated remote worm path is reported; practical access is local-privileged or via control of the OCFS2 backing store.

How to fix it

Apply the Linux kernel change that rejects refcount blocks whose rl_count does not match ocfs2_refcount_recs_per_rb() and whose rl_used exceeds rl_count inside ocfs2_validate_refcount_block() (checks skipped when OCFS2_REFCOUNT_TREE_FL is set, because that union holds an extent list already validated elsewhere). Upgrade to a distribution kernel that includes this ocfs2 validator fix; no per-package fixed versions were supplied with this record, so follow your vendor advisory. Until patched: do not mount untrusted OCFS2 images, restrict CAP_SYS_ADMIN and raw access to OCFS2 backing devices, and avoid reflink/FICLONE on volumes whose integrity is not assured.

How to confirm the fix worked

Confirm running kernels include the ocfs2_validate_refcount_block() rl_count/rl_used capacity checks via distro changelog, CVE mapping, or kernel source/patch level. Inventory exposure with OCFS2 mounts and the ocfs2 module (for example findmnt for type ocfs2 and whether ocfs2 is loaded). On a non-production system, a previously crashing crafted image should now fail at block validation with ocfs2_error() instead of KASAN in ocfs2_insert_refcount_rec()/__ocfs2_increase_refcount(). After upgrade, verify nodes reboot onto the patched kernel and that OCFS2 volumes remount cleanly.

Typical attack path

  1. Gain the ability to mount an OCFS2 image (CAP_SYS_ADMIN), raw-write the OCFS2 backing device, or present a malicious volume to a cluster node
  2. Forge a refcount block that passes ECC/signature/generation checks but sets rl_used/rl_count far above per-block capacity
  3. Arrange an extent cpos that sorts past every real refcount record in that leaf
  4. Trigger reflink/CoW/refcount increase (FICLONE or equivalent) so the kernel walks the forged list
  5. Kernel performs an out-of-bounds record walk and large out-of-bounds memmove
  6. Resulting kernel memory corruption is used for panic/DoS or further in-kernel compromise

How to detect it

There is no network implant or public exploit kit. Hunt kernel logs and crash dumps (dmesg, journalctl --dmesg/-k, kern.log, kdump/vmcore, pstore) for oops, panic, or KASAN reports whose stacks include ocfs2_find_refcount_rec_in_rl, ocfs2_insert_refcount_rec, or __ocfs2_increase_refcount, especially around reflink/FICLONE on OCFS2. After the fix, ocfs2_error() at refcount-block validation means a corrupted or crafted image was presented—treat that as an integrity event. Correlate audit/mount logs for type=ocfs2 mounts, CAP_SYS_ADMIN use, and raw writes to devices backing OCFS2. No APT-specific indicators are known.

  • ocfs2_insert_refcount_rec
  • ocfs2_find_refcount_rec_in_rl
  • __ocfs2_increase_refcount
  • ocfs2_validate_refcount_block
  • KASAN: slab-out-of-bounds in ocfs2_insert_refcount_rec
  • KASAN: slab-out-of-bounds in ocfs2_find_refcount_rec_in_rl
  • KASAN: out-of-bounds in __ocfs2_increase_refcount
  • ocfs2_error

What your security team should do

  • Inventory hosts with the ocfs2 module loaded or OCFS2 filesystems mounted and patch those first
  • Apply vendor/distribution kernel updates that include the ocfs2 refcount-block validator as soon as they ship
  • Until patched, deny mounts of untrusted OCFS2 images and restrict CAP_SYS_ADMIN and raw block-device access to OCFS2 backing stores
  • Alert on kernel oops/KASAN/panic stacks in ocfs2 refcount paths and on ocfs2_error() during refcount-block validation
  • Given no KEV listing, no named actors, and low flat EPSS, do not treat this as internet-wide mass exploitation—concentrate on clustered OCFS2 storage nodes

The record

In the Linux kernel, the following vulnerability has been resolved: ocfs2: validate rl_used against rl_count in refcount block validator ocfs2_find_refcount_rec_in_rl() walks the on-disk refcount record array with: for (; i < le16_to_cpu(rb->rf_records.rl_used); i++) { rec = &rb->rf_records.rl_recs[i]; ... rl_recs[] lives in a single metadata block (4096 bytes on the common configuration), so its real capacity is fixed by ocfs2_refcount_recs_per_rb(sb) (247 records for a 4K block with the 16-byte ocfs2_refcount_rec). rl_used and rl_count are both read directly off disk by ocfs2_validate_refcount_block() and are never checked against that capacity, nor against each other, before any refcount/reflink/CoW operation walks the array. A crafted (or corrupted) refcount block with rl_used == 0xffff makes the loop above walk far past the end of the block, dereferencing rl_recs[i] for i up to 65534. The resulting index is then handed to the sibling ocfs2_insert_refcount_rec(), whose insert-shift does: if (index < le16_to_cpu(rf_list->rl_used)) memmove(&rf_list->rl_recs[index + 1], &rf_list->rl_recs[index], (le16_to_cpu(rf_list->rl_used) - index) * sizeof(struct ocfs2_refcount_rec)); i.e. a memmove() of up to (0xffff - index) * 16 bytes (~1 MiB) from an offset already past the block. This is reachable from an ordinary reflink (FICLONE) against a crafted/corrupted ocfs2 image: attaching an extent whose cpos sorts past every real record in the leaf forces the lookup to run off the end instead of returning early on a match. The attacker model is local: CAP_SYS_ADMIN mounting a crafted or corrupted ocfs2 image, or a raw write to the block device backing an already-mounted ocfs2 filesystem. ocfs2_validate_refcount_block() already validates the block's ECC, signature, rf_blkno and rf_fs_generation, but never rl_count/rl_used against the block's actual on-disk capacity. This is the same class of gap that ocfs2_validate_extent_block() (fs/ocfs2/alloc.c) already closes for the sibling extent-list header, which checks both the record capacity and the "used" bound before any code walks h_list.l_recs[]: if (le16_to_cpu(eb->h_list.l_count) != ocfs2_extent_recs_per_eb(sb)) { rc = ocfs2_error(...); goto bail; } if (le16_to_cpu(eb->h_list.l_next_free_rec) > le16_to_cpu(eb->h_list.l_count)) { rc = ocfs2_error(...); goto bail; } Add the equivalent pair of checks to ocfs2_validate_refcount_block(): reject a refcount block whose rl_count does not match the fixed per-block capacity returned by ocfs2_refcount_recs_per_rb(), and reject rl_used > rl_count. Both checks are skipped when OCFS2_REFCOUNT_TREE_FL is set, because in that case the same union bytes hold an ocfs2_extent_list (rf_list), not the refcount record list (rf_records) -- that layout is already validated separately by ocfs2_validate_extent_block() when the referenced extent block is read. This mirrors the existing "!(rb->rf_flags & OCFS2_REFCOUNT_TREE_FL)" guard used elsewhere in this file (e.g. ocfs2_get_refcount_rec()) to decide whether rf_records or rf_list is the live member of the union. With this in place, a forged rl_used/rl_count is caught at block validation time (ocfs2_error()), consistent with every other corruption check in this function, instead of driving an out-of-bounds read in ocfs2_find_refcount_rec_in_rl() and a subsequent out-of-bounds memmove() in ocfs2_insert_refcount_rec(). Verified against a crafted image on a v6.19 KASAN (KASAN_GENERIC) build: replaying the same reflink (FICLONE) reliably hit a KASAN report in __ocfs2_increase_refcount()/ocfs2_insert_refcount_rec() before this patch, and triggers no report once ocfs2_validate_refcount_block() rejects the forged rl_used/rl_count.

Affected packages

Ecosystem Package Introduced Fixed