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 0/6] ocfs2: fix stale xattr entry pointers and empty header reads
Date: Sat, 24 Oct 2026 23:10:06 +0800 [thread overview]
Message-ID: <20261024151012.1059683-1-joseph.qi@linux.alibaba.com> (raw)
Five defects in the ocfs2 extended attribute code, plus one robustness
measure that belongs with them, all on the paths that move entries
between a block, a bucket and an index tree. They fall into two groups.
Stale entry pointers (patches 1 to 3)
ocfs2_xa_set() writes through a pointer into xh_entries[] that two of
its callers invalidate first. Defragmenting a bucket ends in a sort()
on xe_name_hash, and lib/sort.c is an unstable heapsort, so entries that
share a hash can trade slots. Copying a block into a bucket changes the
order outright, since a block holds its entries in insertion order while
a bucket holds them by hash, yet ocfs2_xattr_update_xattr_search()
relocates the search by the index the entry had in the block. Neither
path compares the entry's name with the one being set, so setxattr() can
replace a neighbouring attribute's value and still report success, or
trip ocfs2_xa_reuse_entry()'s BUG_ON. Patch 1 takes the hash before the
sort; patches 2 and 3 look the entry up again afterwards.
Reads of an empty entry array (patches 4 to 6)
A block and a bucket may both hold no entries: ocfs2_xa_remove_entry()
keeps the last slot when it removes the only one, so an empty bucket
still carries the hash it is keyed by. Three sites index xh_entries[]
without checking xh_count and so read xh_entries[-1], which lands on the
header and comes back as xh_count | xh_free_start << 16. Nothing
faults, but the value is acted on: the collision check reports no
collision for an empty bucket, the divide commits a sentinel hash that
hides part of the key space from ocfs2_xattr_bucket_find(), and the
block to bucket copy claims storage the bucket does not hold. Patches 4
to 6 guard each site and keep the one read of xh_entries[0] that
ocfs2_xa_remove_entry() documents as intentional.
Joseph Qi (6):
ocfs2: read the xattr entry hash before defragmenting the bucket
ocfs2: find the xattr entry again after defragmenting a bucket
ocfs2: find the xattr entry again after converting a block to a bucket
ocfs2: do not read the entry array of an empty xattr bucket
ocfs2: do not index before the entry array when dividing an empty
bucket
ocfs2: do not read the entry array of an empty xattr block
fs/ocfs2/xattr.c | 146 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 123 insertions(+), 23 deletions(-)
--
2.39.3
next reply other threads:[~2026-10-24 15:10 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-24 15:10 Joseph Qi [this message]
2026-10-24 15:10 ` [PATCH 1/6] ocfs2: read the xattr entry hash before defragmenting the bucket Joseph Qi
2026-10-24 15:10 ` [PATCH 2/6] ocfs2: find the xattr entry again after defragmenting a bucket Joseph Qi
2026-10-24 15:10 ` [PATCH 3/6] ocfs2: find the xattr entry again after converting a block to " Joseph Qi
2026-10-24 15:10 ` [PATCH 4/6] ocfs2: do not read the entry array of an empty xattr bucket Joseph Qi
2026-10-24 15:10 ` [PATCH 5/6] ocfs2: do not index before the entry array when dividing an empty bucket Joseph Qi
2026-10-24 15:10 ` [PATCH 6/6] ocfs2: do not read the entry array of an empty xattr block Joseph Qi
2026-10-24 17:37 ` [PATCH 0/6] ocfs2: fix stale xattr entry pointers and empty header reads Andrew Morton
2026-10-25 14:54 ` 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=20261024151012.1059683-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®