From: Joseph Qi <joseph.qi@linux.alibaba.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>,
ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [PATCH v3 0/4] ocfs2: validate suballoc slot and bit of metadata blocks
Date: Tue, 1 Sep 2026 20:52:17 +0800 [thread overview]
Message-ID: <20260901125221.1634686-1-joseph.qi@linux.alibaba.com> (raw)
The ocfs2 metadata validators trust the on-disk suballoc slot and bit
without checking them against the slot range of the mounted filesystem
and the capacity of the block group bitmap. A corrupted image can
carry OCFS2_INVALID_SLOT or another out-of-range slot, or a suballoc
bit beyond the bitmap, and once the corresponding inode, extent block,
xattr block, dir index root or refcount block gets freed, the bad
value goes straight into ocfs2_get_system_file_inode() or
_ocfs2_free_suballoc_bits() and hits a BUG_ON() or runs off the end of
local_system_inodes[].
This series rejects such values at read time, in the existing
validators, so corrupted objects fail with -EROFS (and a read-only
remount) instead of crashing:
patch 1 restricts OCFS2_INVALID_SLOT dinodes to system inodes,
completing fe7a283b3916 ("ocfs2: add suballoc slot check in
ocfs2_validate_inode_block()"), and turns the "system file
state is ambiguous" BUG_ON() in ocfs2_read_locked_inode() into
an ocfs2_error();
patch 2 rejects oversized dinode suballoc bits;
patch 3 validates the suballoc slot and bit of xattr and dir index
blocks;
patch 4 validates the suballoc slot and bit of extent and refcount
blocks.
The checks only enforce what the kernel and mkfs.ocfs2 already write:
a valid slot from meta_ac->ac_alloc_slot and a bit within the block
group bitmap, with system inodes carrying OCFS2_INVALID_SLOT plus
OCFS2_SYSTEM_FL and extent blocks using slot 0. Nothing changes for
healthy filesystems.
Each new check was exercised under QEMU by corrupting the field in
question with an out-of-range value; with the series applied the
access fails with -EROFS and the filesystem remounts read-only instead
of hitting the BUG_ON().
Changes since v2:
- Patch 2 converts the BUG_ON() against ocfs2_bits_per_group() in
_ocfs2_free_suballoc_bits() to ocfs2_error(). That bound is
derived from cl_cpg/cl_bpc of the allocator dinode, which is not
validated against the actual group capacity and can be
artificially smaller on a corrupted image, so the static
validation bound alone is not sufficient.
- Patch 2 also derives ocfs2_suballoc_bits_per_block() from
ocfs2_group_bitmap_size(). With discontig_bg enabled the
suballocator bitmap is capped at OCFS2_MAX_BG_BITMAP_SIZE (2048
bits), which the previous blocksize-based bound missed, letting a
corrupted bit in [2048, bits-per-block) slip through validation.
- Patch 3 also verifies dr_blkno against the physical block number
in ocfs2_validate_dx_root() like the extent and xattr block
validators do, so misplaced dir index root blocks are rejected.
- Patch 4 converts the remaining BUG_ON() against group->bg_bits in
_ocfs2_free_suballoc_bits() to ocfs2_error(); group descriptor
validation only guarantees bg_bits within the physical bitmap
size, and otherwise ocfs2_block_group_clear_bits() could clear
bits beyond bg_bitmap.
- The suballoc bit comments in the validators are updated
accordingly.
Changes since v1:
- Patch 1 also turns the system-file-state BUG_ON() in
ocfs2_read_locked_inode() into ocfs2_error(). i_flags is on-disk
data, so a crafted dinode with OCFS2_SYSTEM_FL passes the slot
check and still hit that BUG() on a plain lookup.
- Patches 2-4 now bound the suballoc bit against the block group
bitmap capacity (block size minus the group descriptor header)
instead of the raw block size, using a new
ocfs2_suballoc_bits_per_block() helper.
- Patch 3 also validates xb_suballoc_bit and dr_suballoc_bit.
- Patch 4 also validates h_suballoc_bit, and adds rf_suballoc_slot
and rf_suballoc_bit checks in ocfs2_validate_refcount_block().
Joseph Qi (4):
ocfs2: restrict OCFS2_INVALID_SLOT suballoc slot to system inodes
ocfs2: validate suballoc bit during inode read
ocfs2: validate suballoc slot and bit of xattr and dir index blocks
ocfs2: validate suballoc slot and bit of extent and refcount blocks
fs/ocfs2/alloc.c | 27 +++++++++++++++++++++
fs/ocfs2/dir.c | 35 +++++++++++++++++++++++++++
fs/ocfs2/inode.c | 53 ++++++++++++++++++++++++++++++++++-------
fs/ocfs2/ocfs2.h | 12 ++++++++++
fs/ocfs2/refcounttree.c | 27 +++++++++++++++++++++
fs/ocfs2/suballoc.c | 33 +++++++++++++++++++++----
fs/ocfs2/xattr.c | 25 +++++++++++++++++++
7 files changed, 199 insertions(+), 13 deletions(-)
--
2.39.3
next reply other threads:[~2026-09-01 12:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 12:52 Joseph Qi [this message]
2026-09-01 12:52 ` [PATCH v3 1/4] ocfs2: restrict OCFS2_INVALID_SLOT suballoc slot to system inodes Joseph Qi
2026-09-01 12:52 ` [PATCH v3 2/4] ocfs2: validate suballoc bit during inode read Joseph Qi
2026-09-01 12:52 ` [PATCH v3 3/4] ocfs2: validate suballoc slot and bit of xattr and dir index blocks Joseph Qi
2026-09-01 12:52 ` [PATCH v3 4/4] ocfs2: validate suballoc slot and bit of extent and refcount blocks Joseph Qi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260901125221.1634686-1-joseph.qi@linux.alibaba.com \
--to=joseph.qi@linux.alibaba.com \
--cc=akpm@linux-foundation.org \
--cc=heming.zhao@suse.com \
--cc=jlbec@evilplan.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark@fasheh.com \
--cc=ocfs2-devel@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®