mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [BUG REPORT] xfs: log recovery dereferences an unvalidated ilf_boffset - KASAN use-after-free / page fault at mount time
@ 2026-10-31  4:00 Guikun Yang
  0 siblings, 0 replies; only message in thread
From: Guikun Yang @ 2026-10-31  4:00 UTC (permalink / raw)
  To: linux-xfs, Darrick J. Wong, Carlos Maiolino, Dave Chinner
  Cc: linux-kernel, Brian Foster

Hi,

We found that xlog_recover_inode_commit_pass2() uses the on-disk
ilf_boffset field to index into the inode cluster buffer without any
bounds validation, and we can drive a KASAN use-after-free or an
unrecoverable page fault at mount time with a crafted log record.

We are aware of the RFC series "[PATCH 00/48] Validate journal log
items during log recovery" (2026-10-13), whose 35/48 validates the
inode item format header via xfs_imap()-derived boffset/blkno. This
report is not a proposal to fix it differently: it provides an
independent reproducer plus KASAN traces for the vulnerability as it
stands in mainline today (7.3.0 and current master both still carry
the unvalidated dereference), which may be useful as a test case for
the series.

The code, current mainline (fs/xfs/xfs_inode_item_recover.c:356):

    error =3D xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,
                    0, &bp, &xfs_inode_buf_ops);
    if (error)
            goto error;
    ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
    dip =3D xfs_buf_offset(bp, in_f->ilf_boffset);       /* no check */

    if (XFS_IS_CORRUPT(mp, !xfs_verify_magic16(bp, dip->di_magic)))

xfs_buf_offset() is bp->b_addr + offset with no check. ilf_boffset is
an int32_t read straight from the log item format region
(libxfs/xfs_log_format.h:301). The only writers are the in-memory
im_boffset copy and the 32-bit format converter, which copies the
value verbatim. On the read side we could not find any validation:
the magic check above dereferences the resulting pointer, and on
v3 inodes dip->di_lsn / di_version / di_flushiter are read next.
xfs_log_dinode_to_disk() then writes a full log dinode through the
same pointer if the checks happen to pass. On a CONFIG_XFS_DEBUG=3Dn
kernel the ASSERT()s compile away entirely.

The buffer item path in the same recovery machinery had this class
of bug fixed in July (813f8136a2ce, "xfs: bounds-check buffer log
item's dirty bitmap"), which added the comment at
xfs_buf_item_recover.c:490-497 stating the logged fields are
attacker-controlled and that a real check is needed rather than an
ASSERT(). ilf_boffset is the same pattern in the inode item path and
is, as of today, still unprotected in mainline.

Trigger (no special mount options):

 1. mount an XFS filesystem, create a couple of files, crash the
    machine (sysrq-c) without unmounting, so the log holds inode log
    items;
 2. edit one inode log item's ilf_boffset in the log area to a wild
    value (the record CRC must be recomputed; CRC only protects
    against accidental corruption);
 3. mount the image again. Mount-time recovery replays the inode
    item and dereferences b_addr + ilf_boffset.

With ilf_boffset =3D 0x10000000 on a 64MB image (KASAN kernel, 7.3.0):

    BUG: KASAN: use-after-free in xlog_recover_inode_commit_pass2+0x1187/0x1f=
70
    Read of size 2 at addr ffff888014914000 by task init/1
    CPU: 0 UID: 0 PID: 1 Comm: init Not tainted 7.3.0 #23
    Call Trace:
     xlog_recover_inode_commit_pass2+0x1187/0x1f70
     xlog_recover_items_pass2+0x105/0x280
     xlog_recover_commit_trans+0x7e6/0x9d0
     xlog_recovery_process_trans+0x1a1/0x1c0
     xlog_recover_process_ophdr+0x1ea/0x400
     xlog_recover_process_data+0x12d/0x3c0
     xlog_recover_process+0x10d/0x390
     xlog_do_recovery_pass+0x8cf/0xd40
     xlog_do_log_recovery+0x89/0xb0
     xlog_do_recover+0x78/0x410
     xlog_recover+0x2d0/0x4e0
     xfs_log_mount+0x23a/0x480
     xfs_mountfs+0xfe7/0x20b0
     xfs_fs_fill_super+0x15dc/0x1e00
     get_tree_bdev_flags+0x36b/0x5f0

    Kernel panic - not syncing: KASAN: panic_on_warn set ...

With ilf_boffset =3D 0x40000000 instead:

    BUG: unable to handle page fault for address: ffffed10088a2800
    Oops: Oops: 0000 [#1] SMP KASAN PTI
    Kernel panic - not syncing: Fatal exception

With the original value the same log replays cleanly and the
filesystem mounts; the behavior difference is solely the unchecked
offset. Deterministic, reproduced 3/3 on a self-built 7.3.0 kernel
(CONFIG_KASAN_GENERIC=3Dy, CONFIG_XFS_FS=3Dy, CONFIG_XFS_DEBUG=3Dn).

Two sibling fields in log-replay formats share the shape (offset or
count from disk feeding a buffer access with only an ASSERT, or
nothing): qlf_boffset applied via xfs_buf_offset() at
xfs_dquot_item_recover.c:135, and bb_numrecs used as the memcpy count
in xfs_bmbt_to_bmdr() (libxfs/xfs_bmap_btree.c:174-176). We mention
them as context only; we expect the RFC series covers them as part of
"every log item type".

ilf_boffset has been unvalidated since it was introduced:

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")

A natural fix mirrors 813f8136a2ce: validate that ilf_boffset lies
within the buffer that was just read (bp->b_length) with
XFS_IS_CORRUPT() and fail recovery with -EFSCORRUPTED. The RFC 35/48
approach (derive from ilf_ino via xfs_imap() and require a match) is
stronger and we are happy to test the series against our reproducer
if that is useful.

We frame this the same way 813f8136a2ce was framed: the input is the
log itself, which recovery must already treat as untrusted on
unclean mounts; we are not claiming a privilege-boundary crossing
beyond "whoever controls the device image controls the log".

The reproducer bundle (image builder + log patcher + CRC
recomputation matching xlog_cksum(), guest init, run script, and a
pre-baked dirty image) is available on request.

Environment: QEMU/KVM x86_64, 1 vCPU, kernel 7.3.0 self-built with
CONFIG_KASAN_GENERIC=3Dy, CONFIG_UBSAN=3Dy, CONFIG_XFS_FS=3Dy,
CONFIG_XFS_DEBUG=3Dn.

Thanks,
Guikun Yang


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-01 13:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-31  4:00 [BUG REPORT] xfs: log recovery dereferences an unvalidated ilf_boffset - KASAN use-after-free / page fault at mount time Guikun Yang

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®