From: Jenny Guanni Qu <qguanni@gmail.com>
To: shaggy@kernel.org
Cc: jfs-discussion@lists.sourceforge.net,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Jenny Guanni Qu <qguanni@gmail.com>,
syzbot+a98891ce2318fe7baf05@syzkaller.appspotmail.com
Subject: [PATCH] jfs: fix use-after-free in jfs_readdir on legacy non-indexed directories
Date: Sat, 13 Jun 2026 04:12:04 +0900 [thread overview]
Message-ID: <20260612191204.95876-1-qguanni@gmail.com> (raw)
In the legacy (non-indexed) readdir path, jfs_readdir calls dtReadNext
to advance through the directory's dtree. When dtReadNext reaches the
last leaf page, it frees the metapage via DT_PUTPAGE(mp), sets bn = -1,
and falls through to the out label, which stores the stale mp pointer
into btstack->top->mp.
Back in jfs_readdir, DT_GETSEARCH dereferences btstack.top->mp to
extract the dtpage pointer. It guards this with "if (BN)", intending to
distinguish root (bn=0) from non-root pages, but the -1 EOF sentinel
also passes this check, causing a read from the freed metapage slab
object.
The existing code already had the correct EOF check ("offset beyond
directory eof?") immediately after DT_GETSEARCH, but the dereference
inside the macro fires first. Fix this by moving the bn < 0 check
before the DT_GETSEARCH call, reading btstack.top->bn directly since
the local bn variable is not yet populated.
Also null out the stale mp pointer in dtReadNext when bn is -1, so the
btstack does not retain a dangling pointer to freed memory.
The buggy ordering predates the git history; the EOF check has followed
DT_GETSEARCH since the initial JFS merge, so there is no specific
commit to reference in a Fixes: tag.
Reported-by: syzbot+a98891ce2318fe7baf05@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a98891ce2318fe7baf05
Cc: stable@vger.kernel.org
Signed-off-by: Jenny Guanni Qu <qguanni@gmail.com>
---
Reproduced the crash on an x86_64 KASAN kernel (v7.1-rc6) using a C
reproducer that mounts a JFS image, clears JFS_DIR_INDEX in the
superblock to force the legacy non-indexed readdir path, and calls
getdents64 past the last leaf page. The faulting access resolves via
faddr2line to the DT_GETSEARCH dereference in jfs_readdir, and the free
to release_metapage in dtReadNext, matching the syzbot report. syzbot's
own published C reproducer produces an identical crash signature on the
same kernel.
With this patch applied (v7.1-rc8), the same reproducer drives the
identical code path (600 entries, repeated getdents64 calls through the
legacy jfs_readdir loop) and completes with no KASAN report.
fs/jfs/jfs_dtree.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index ac0f79fafaca..037121587571 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2874,14 +2874,14 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
ctx->pos = DIREND;
return 0;
}
- /* get start leaf page and index */
- DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
-
/* offset beyond directory eof ? */
- if (bn < 0) {
+ if (btstack.top->bn < 0) {
ctx->pos = DIREND;
return 0;
}
+
+ /* get start leaf page and index */
+ DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
}
dirent_buf = __get_free_page(GFP_KERNEL);
@@ -3293,7 +3293,7 @@ static int dtReadNext(struct inode *ip, loff_t * offset,
btsp = btstack->top;
btsp->bn = bn;
btsp->index = dtoffset->index;
- btsp->mp = mp;
+ btsp->mp = (bn == -1) ? NULL : mp;
return 0;
}
--
2.50.1 (Apple Git-155)
reply other threads:[~2026-06-12 19:12 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=20260612191204.95876-1-qguanni@gmail.com \
--to=qguanni@gmail.com \
--cc=jfs-discussion@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=shaggy@kernel.org \
--cc=stable@vger.kernel.org \
--cc=syzbot+a98891ce2318fe7baf05@syzkaller.appspotmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome