From: Andrew Morton <akpm@linux-foundation.org>
To: mm-commits@vger.kernel.org,piaojun@huawei.com,mark@fasheh.com,junxiao.bi@oracle.com,jlbec@evilplan.org,heming.zhao@suse.com,gechangwei@live.cn,joseph.qi@linux.alibaba.com,akpm@linux-foundation.org
Subject: [merged mm-nonmm-stable] ocfs2-validate-suballoc-slot-and-bit-of-extent-and-refcount-blocks.patch removed from -mm tree
Date: Tue, 06 Oct 2026 19:04:41 -0700 [thread overview]
Message-ID: <20261007020442.4D2DC1F0089B@smtp.kernel.org> (raw)
The quilt patch titled
Subject: ocfs2: validate suballoc slot and bit of extent and refcount blocks
has been removed from the -mm tree. Its filename was
ocfs2-validate-suballoc-slot-and-bit-of-extent-and-refcount-blocks.patch
This patch was dropped because it was merged into the mm-nonmm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
Subject: ocfs2: validate suballoc slot and bit of extent and refcount blocks
Date: Tue, 1 Sep 2026 20:52:21 +0800
ocfs2_validate_extent_block() and ocfs2_validate_refcount_block() do not
validate h_suballoc_slot, h_suballoc_bit, rf_suballoc_slot and
rf_suballoc_bit at all. Since extent blocks and refcount blocks are
allocated from a per-slot suballocator at runtime, their suballoc slots
must be within range and their suballoc bits must fit in a block group
bitmap.
Otherwise a corrupted image can carry an out-of-range slot. When the
extent block is freed, ocfs2_cache_extent_block_free() caches it and
ocfs2_free_cached_blocks() later passes the unvalidated slot to
ocfs2_get_system_file_inode(); when the refcount block is freed,
ocfs2_remove_refcount_extent() passes it via ocfs2_cache_block_dealloc().
get_local_system_inode() will then either hit BUG_ON(slot ==
OCFS2_INVALID_SLOT) or compute an out-of-bounds index into the
local_system_inodes array. Similarly an oversized suballoc bit will error
out the filesystem in _ocfs2_free_suballoc_bits().
Furthermore group descriptor validation only guarantees bg_bits within the
physical bitmap size, so a corrupted image can still carry a suballoc bit
beyond bg_bits, which would let ocfs2_block_group_clear_bits() clear bits
beyond bg_bitmap. Convert the remaining BUG_ON against group->bg_bits in
_ocfs2_free_suballoc_bits() to ocfs2_error() as well.
Reject out-of-range suballoc slots and oversized suballoc bits during
validation.
Link: https://lore.kernel.org/20260901125221.1634686-5-joseph.qi@linux.alibaba.com
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
---
fs/ocfs2/alloc.c | 27 +++++++++++++++++++++++++++
fs/ocfs2/refcounttree.c | 27 +++++++++++++++++++++++++++
fs/ocfs2/suballoc.c | 15 ++++++++++++++-
3 files changed, 68 insertions(+), 1 deletion(-)
--- a/fs/ocfs2/alloc.c~ocfs2-validate-suballoc-slot-and-bit-of-extent-and-refcount-blocks
+++ a/fs/ocfs2/alloc.c
@@ -925,6 +925,33 @@ static int ocfs2_validate_extent_block(s
goto bail;
}
+ /*
+ * Extent blocks are allocated from a per-slot suballocator, so the
+ * slot must be in range. Otherwise freeing the block passes it to
+ * get_local_system_inode(), which hits BUG_ON() for
+ * OCFS2_INVALID_SLOT or computes an out-of-bounds index otherwise.
+ */
+ if ((u32)le16_to_cpu(eb->h_suballoc_slot) >= OCFS2_SB(sb)->max_slots) {
+ rc = ocfs2_error(sb,
+ "Extent block #%llu has an invalid h_suballoc_slot of %u\n",
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(eb->h_suballoc_slot));
+ goto bail;
+ }
+
+ /*
+ * Similarly the suballoc bit must fit in a block group bitmap.
+ * Otherwise freeing the block will pass the oversized bit to
+ * _ocfs2_free_suballoc_bits() and trigger ocfs2_error() there.
+ */
+ if (le16_to_cpu(eb->h_suballoc_bit) >= ocfs2_suballoc_bits_per_block(sb)) {
+ rc = ocfs2_error(sb,
+ "Extent block #%llu has an invalid h_suballoc_bit of %u\n",
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(eb->h_suballoc_bit));
+ goto bail;
+ }
+
if (le16_to_cpu(eb->h_list.l_count) != ocfs2_extent_recs_per_eb(sb)) {
rc = ocfs2_error(sb,
"Extent block #%llu has invalid l_count %u (expected %u)\n",
--- a/fs/ocfs2/refcounttree.c~ocfs2-validate-suballoc-slot-and-bit-of-extent-and-refcount-blocks
+++ a/fs/ocfs2/refcounttree.c
@@ -118,6 +118,33 @@ static int ocfs2_validate_refcount_block
}
/*
+ * Refcount blocks are allocated from a per-slot suballocator, so the
+ * slot must be in range. Otherwise freeing the block passes it to
+ * get_local_system_inode(), which hits BUG_ON() for
+ * OCFS2_INVALID_SLOT or computes an out-of-bounds index otherwise.
+ */
+ if ((u32)le16_to_cpu(rb->rf_suballoc_slot) >= OCFS2_SB(sb)->max_slots) {
+ rc = ocfs2_error(sb,
+ "Refcount block #%llu has an invalid rf_suballoc_slot of %u\n",
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(rb->rf_suballoc_slot));
+ goto out;
+ }
+
+ /*
+ * Similarly the suballoc bit must fit in a block group bitmap.
+ * Otherwise freeing the block will pass the oversized bit to
+ * _ocfs2_free_suballoc_bits() and trigger ocfs2_error() there.
+ */
+ if (le16_to_cpu(rb->rf_suballoc_bit) >= ocfs2_suballoc_bits_per_block(sb)) {
+ rc = ocfs2_error(sb,
+ "Refcount block #%llu has an invalid rf_suballoc_bit of %u\n",
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(rb->rf_suballoc_bit));
+ goto out;
+ }
+
+ /*
* rf_records (rl_count/rl_used/rl_recs[]) is only meaningful when
* this block is not an interior tree block (OCFS2_REFCOUNT_TREE_FL);
* in that case the same union bytes hold an extent list (rf_list)
--- a/fs/ocfs2/suballoc.c~ocfs2-validate-suballoc-slot-and-bit-of-extent-and-refcount-blocks
+++ a/fs/ocfs2/suballoc.c
@@ -3070,7 +3070,20 @@ static int _ocfs2_free_suballoc_bits(han
}
group = (struct ocfs2_group_desc *) group_bh->b_data;
- BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits));
+ /*
+ * Group descriptor validation only guarantees bg_bits within the
+ * physical bitmap size, so double check the freeing range here.
+ * Otherwise ocfs2_block_group_clear_bits() would clear bits beyond
+ * bg_bitmap.
+ */
+ if ((count + start_bit) > le16_to_cpu(group->bg_bits)) {
+ status = ocfs2_error(alloc_inode->i_sb,
+ "Group descriptor #%llu has %u bits, cannot free bits %u+%u\n",
+ (unsigned long long)le64_to_cpu(group->bg_blkno),
+ le16_to_cpu(group->bg_bits),
+ count, start_bit);
+ goto bail;
+ }
if (ocfs2_is_cluster_bitmap(alloc_inode))
old_bg_contig_free_bits = group->bg_contig_free_bits;
_
Patches currently in -mm which might be from joseph.qi@linux.alibaba.com are
ocfs2-retain-all-security-xattrs-during-inode-creation.patch
ocfs2-restore-erange-check-in-ocfs2_xattr_tree_list_index_block.patch
ocfs2-fix-possible-deadlock-between-nfs_sync_rwlock-and-fs_reclaim.patch
reply other threads:[~2026-10-07 2:04 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20261007020442.4D2DC1F0089B@smtp.kernel.org \
--to=akpm@linux-foundation.org \
--cc=gechangwei@live.cn \
--cc=heming.zhao@suse.com \
--cc=jlbec@evilplan.org \
--cc=joseph.qi@linux.alibaba.com \
--cc=junxiao.bi@oracle.com \
--cc=mark@fasheh.com \
--cc=mm-commits@vger.kernel.org \
--cc=piaojun@huawei.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.