Linux XFS filesystem development
 help / color / mirror / Atom feed
From: Weiming Shi <bestswngs@gmail.com>
To: Carlos Maiolino <cem@kernel.org>, "Darrick J . Wong" <djwong@kernel.org>
Cc: linux-xfs@vger.kernel.org, linux-kernel@vger.kernel.org,
	xmei5@asu.edu, Weiming Shi <bestswngs@gmail.com>
Subject: [PATCH v3 0/3] xfs: add a log item verification layer to recovery
Date: Sun, 19 Jul 2026 04:29:20 -0700	[thread overview]
Message-ID: <20260719112923.226550-1-bestswngs@gmail.com> (raw)

Log recovery rebuilds each log item from the ophdr regions in the journal
and then casts those regions back to their format structures to drive
replay. The region layout it trusts to do this - the item type, the region
count, and the region sizes - all come from the log, so a crafted or
corrupt image can present a malformed item that recovery dereferences.
The reported case is an XFS_LI_INODE item that declares two regions but
logs only one, leaving ri_buf[1] NULL and faulting mount-time recovery in
xlog_recover_inode_commit_pass2().

v2 rejected an item whose logged region count did not reach the declared
count with a single check in xlog_recover_commit_trans(). As Dave pointed
out, that only found the one missing check and left the comprehensive
verification of the recovered item structure undone, at the wrong layer.
v3 instead verifies each item where it is first decoded from the log, in
xlog_recover_add_to_trans(), before that data is used to size, build,
decode or replay anything:

  - When an item header is decoded, resolve the item type and bound the
    region count it declares within the minimum and maximum a log item of
    that type is formatted with. The upper bound keeps the region array
    from being oversized; the lower bound stops an item that declares fewer
    regions than its replay code indexes, e.g. a dquot with qlf_size == 1
    that still reaches ri_buf[1]. Reject a continuation that has no region
    to extend.

  - When an item is fully decoded (the next item's header arrives, or the
    commit record does), confirm it received all its declared regions and
    run the item type's verifier, if it has one.

  - Add the first per-type verifier, for inode items, and drop the
    equivalent open-coded checks that were scattered through the inode
    pass2 path.

The generic checks bound and complete the region layout - the item type,
the region count within a per-type [min, max], and that every declared
region arrived - for every item type. The per-region size and structure
checks are type-specific and live in the ->verify method; this series adds
the inode verifier, and the other types can grow their own the same way.

Not addressed here are the ->verify checks for the remaining types,
including the non-header region size checks and the content-driven indices
that the region count alone does not bound. Two such cases are known: the
btree-root fork formats convert from a larger in-core form on replay, so
their region size does not bound bb_numrecs in xfs_bmbt_to_bmdr() and the
rt converters; and buffer replay walks ri_buf[] by the blf_data_map bit
runs rather than by the region count. A buffer ->verify and a bb_numrecs
clamp are left as follow-ups.

v3:
  - Reworked from the single completeness check in
    xlog_recover_commit_trans() into a verification layer at the
    region-assembly boundary in xlog_recover_add_to_trans(), as Dave
    suggested: a header check at decode time (item type known, region count
    within [min, max]) and a completeness/structure check when the item is
    fully decoded, with per-type verifiers hanging off
    xlog_recover_item_ops. Added the inode verifier and a continuation
    underflow guard.

v2:
  - Dropped the piecemeal per-check validation in the inode pass2 path.

Weiming Shi (3):
  xfs: verify log item headers when they are decoded during recovery
  xfs: verify recovered log items are complete before replaying them
  xfs: add an inode log item recovery verifier

 fs/xfs/libxfs/xfs_log_recover.h |  17 +++++
 fs/xfs/xfs_attr_item.c          |   4 ++
 fs/xfs/xfs_bmap_item.c          |   4 ++
 fs/xfs/xfs_dquot_item_recover.c |   4 ++
 fs/xfs/xfs_exchmaps_item.c      |   4 ++
 fs/xfs/xfs_extfree_item.c       |   8 +++
 fs/xfs/xfs_icreate_item.c       |   2 +
 fs/xfs/xfs_inode_item_recover.c |  89 ++++++++++++++++++-----
 fs/xfs/xfs_log_recover.c        | 121 +++++++++++++++++++++++---------
 fs/xfs/xfs_refcount_item.c      |   8 +++
 fs/xfs/xfs_rmap_item.c          |   8 +++
 11 files changed, 221 insertions(+), 48 deletions(-)


base-commit: 8c13415c8a4383447c21ec832b20b3b283f0e01a
-- 
2.43.0


             reply	other threads:[~2026-07-19 11:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-19 11:29 Weiming Shi [this message]
2026-07-19 11:29 ` [PATCH v3 1/3] xfs: verify log item headers when they are decoded during recovery Weiming Shi
2026-07-19 11:29 ` [PATCH v3 2/3] xfs: verify recovered log items are complete before replaying them Weiming Shi
2026-07-19 11:29 ` [PATCH v3 3/3] xfs: add an inode log item recovery verifier Weiming Shi

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=20260719112923.226550-1-bestswngs@gmail.com \
    --to=bestswngs@gmail.com \
    --cc=cem@kernel.org \
    --cc=djwong@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=xmei5@asu.edu \
    /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