CVE-2026-89493: ocfs2: validate rl_used against rl_count in refcount block validator

Published Sep 11, 2026
·
Updated

In the Linux kernel, the following vulnerability has been resolved:

ocfs2: validate rlused against rlcount in refcount block validator

ocfs2findrefcountrecinrl() walks the on-disk refcount record array with:

for (; i < le16tocpu(rb->rfrecords.rlused); i++) { rec = &rb->rfrecords.rlrecs[i]; ...

rlrecs[] lives in a single metadata block (4096 bytes on the common configuration), so its real capacity is fixed by ocfs2refcountrecsperrb(sb) (247 records for a 4K block with the 16-byte ocfs2refcountrec). rlused and rlcount are both read directly off disk by ocfs2validaterefcountblock() 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 rlused == 0xffff makes the loop above walk far past the end of the block, dereferencing rlrecs[i] for i up to 65534. The resulting index is then handed to the sibling ocfs2insertrefcountrec(), whose insert-shift does:

if (index < le16tocpu(rflist->rlused)) memmove(&rflist->rlrecs[index + 1], &rflist->rlrecs[index], (le16tocpu(rflist->rlused) - index) sizeof(struct ocfs2refcountrec));

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: CAPSYSADMIN mounting a crafted or corrupted ocfs2 image, or a raw write to the block device backing an already-mounted ocfs2 filesystem.

ocfs2validaterefcountblock() already validates the block's ECC, signature, rfblkno and rffsgeneration, but never rlcount/rlused against the block's actual on-disk capacity. This is the same class of gap that ocfs2validateextentblock() (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 hlist.lrecs[]:

if (le16tocpu(eb->hlist.lcount) != ocfs2extentrecspereb(sb)) { rc = ocfs2error(...); goto bail; }

if (le16tocpu(eb->hlist.lnextfreerec) > le16tocpu(eb->hlist.lcount)) { rc = ocfs2error(...); goto bail; }

Add the equivalent pair of checks to ocfs2validaterefcountblock(): reject a refcount block whose rlcount does not match the fixed per-block capacity returned by ocfs2refcountrecsperrb(), and reject rlused > rlcount. Both checks are skipped when OCFS2REFCOUNTTREEFL is set, because in that case the same union bytes hold an ocfs2extentlist (rflist), not the refcount record list (rfrecords) -- that layout is already validated separately by ocfs2validateextentblock() when the referenced extent block is read. This mirrors the existing "!(rb->rfflags & OCFS2REFCOUNTTREEFL)" guard used elsewhere in this file (e.g. ocfs2getrefcountrec()) to decide whether rfrecords or rflist is the live member of the union.

With this in place, a forged rlused/rlcount is caught at block validation time (ocfs2error()), consistent with every other corruption check in this function, instead of driving an out-of-bounds read in ocfs2findrefcountrecinrl() and a subsequent out-of-bounds memmove() in ocfs2insertrefcountrec().

Verified against a crafted image on a v6.19 KASAN (KASANGENERIC) build: replaying the same reflink (FICLONE) reliably hit a KASAN report in ocfs2increaserefcount()/ocfs2insertrefcountrec() before this patch, and triggers no report once ocfs2validaterefcountblock() rejects the forged rlused/rlcount.

Affected Software

1 affected component
Oracle Linux kernel

Event History

Sep 11, 2026
CVE Published
via MITRE·07:43 PM
Data Sourced
via MITRE·07:43 PM
Description

Frequently Asked Questions

1

Which environments are exposed to this issue?

Linux systems using OCFS2 are exposed when they perform refcount, reflink, or copy-on-write operations that walk an on-disk refcount record array. The issue concerns malformed or corrupted OCFS2 refcount blocks.

2

What does an attacker need to control to trigger the vulnerable path?

The attacker needs a crafted on-disk refcount block, or an existing refcount block must be corrupted. In particular, a malicious rl_used value can cause the kernel to iterate beyond the metadata block's refcount-record array.

3

What on-disk values indicate a dangerous refcount block?

A refcount block is dangerous when rl_used or rl_count exceeds the record capacity of its metadata block, or when the two values are inconsistent. On a common 4K-block configuration, the described record-array capacity is 247 records; rl_used set to 0xffff can drive traversal far beyond that boundary.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203