mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] jfs: reject xtree pages whose BT_ROOT flag does not match
@ 2026-10-20 16:32 Nicholas Velten via B4 Relay
  0 siblings, 0 replies; only message in thread
From: Nicholas Velten via B4 Relay @ 2026-10-20 16:32 UTC (permalink / raw)
  To: Dave Kleikamp
  Cc: jfs-discussion, linux-kernel, syzbot+43706fd1eb4c8dccdfe6,
	Nicholas Velten

From: Nicholas Velten <nicholasfvelten@gmail.com>

syzbot reports a crash in release_metapage() when an inode from a
corrupted JFS image is evicted:

  Oops: stack segment: 0000 [#1] SMP KASAN PTI
  RIP: 0010:release_metapage+0x9e/0xab0 fs/jfs/jfs_metapage.c:870
  Call Trace:
   xtTruncate+0xecd/0x2f20 fs/jfs/jfs_xtree.c
   jfs_free_zero_link+0x35b/0x4c0 fs/jfs/namei.c:759
   jfs_evict_inode+0x363/0x440 fs/jfs/inode.c:159
   evict+0x61e/0xb10 fs/inode.c:837
   ...

The xtree root of a regular file is embedded in the inode, and
xt_getpage() returns it for bn == 0 with a pseudo metapage. Callers
such as xtTruncate() and xtTruncate_pmap() then decide whether they
hold the root by testing the on-disk p->header.flag & BT_ROOT. In the
reproducer's image a regular file has an xtroot flag of 0 instead of
DXD_INDEX | BT_ROOT | BT_LEAF, so xtTruncate() takes the non-root path
for the embedded root and releases the pseudo metapage as if it were
a real page, dereferencing an invalid folio.

xt_getpage() already validates nextindex and maxentry for both the
root and regular pages. Also reject a page whose BT_ROOT flag does not
match where it came from: the root (bn == 0) must have it set and any
other page must not. Healthy trees always satisfy this, since
xtInitRoot() sets BT_ROOT and xtSplitRoot()/xtSplitPage() never copy it
to a child page.

Tested in a KASAN guest: the syzbot reproducer crashes the unpatched
kernel. With this patch the bad page is reported as
"xt_getpage: xtree page corrupt" and the reproducer runs to completion.
On a clean mkfs.jfs image, writing 40 separate extents to one file
(forcing a root split), remounting, truncating, renaming over an
existing file and remounting again still works, with the data
unchanged.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+43706fd1eb4c8dccdfe6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=43706fd1eb4c8dccdfe6
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Nicholas Velten <nicholasfvelten@gmail.com>
---
syzbot sent an AI-generated RFC for this bug in May
(https://lore.kernel.org/all/938f325a-46c6-4ade-8a21-b3271963810c@mail.kernel.org/),
which also bundled unrelated txnmgr/logmgr changes and got no replies.
This patch only addresses the xtree root confusion, by validating the
flag in xt_getpage() next to the existing nextindex/maxentry checks.

The reproducer is syzbot's C repro, run in a virtme-ng KASAN guest built
from next-20261009.

Not tested: architectures other than x86_64, and jfs_fsck on the
rejected image.
---
 fs/jfs/jfs_xtree.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index 28c3cf960..3a5f9d035 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -121,7 +121,8 @@ static inline xtpage_t *xt_getpage(struct inode *ip, s64 bn, struct metapage **m
 		(le16_to_cpu(p->header.nextindex) >
 			le16_to_cpu(p->header.maxentry)) ||
 		(le16_to_cpu(p->header.maxentry) >
-			((bn == 0) ? XTROOTMAXSLOT : PSIZE >> L2XTSLOTSIZE))) {
+			((bn == 0) ? XTROOTMAXSLOT : PSIZE >> L2XTSLOTSIZE)) ||
+		((bn == 0) != !!(p->header.flag & BT_ROOT))) {
 		jfs_error(ip->i_sb, "xt_getpage: xtree page corrupt\n");
 		BT_PUTPAGE(*mp);
 		*mp = NULL;

---
base-commit: becb95e45ef0dda9ffb35156d909d3da7a2789c3
change-id: 20261020-jfs-xtroot-check-e2c2159498b0

Best regards,
--  
Nicholas Velten <nicholasfvelten@gmail.com>



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

only message in thread, other threads:[~2026-10-20 16:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-20 16:32 [PATCH] jfs: reject xtree pages whose BT_ROOT flag does not match Nicholas Velten via B4 Relay

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®