From: Tristan Madani <tristmd@gmail.com>
To: Dave Kleikamp <shaggy@kernel.org>
Cc: jfs-discussion@lists.sourceforge.net,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Tristan Madani <tristan@talencesecurity.com>,
syzbot+aa6df9d3b383bf5f047f@syzkaller.appspotmail.com
Subject: [PATCH] jfs: validate lv bounds in diWrite to prevent slab-out-of-bounds
Date: Fri, 1 May 2026 11:02:30 +0000 [thread overview]
Message-ID: <20260501110230.38407-1-tristmd@gmail.com> (raw)
From: Tristan Madani <tristan@talencesecurity.com>
diWrite() copies btree root data from the in-memory inode to the
on-disk dinode using lv->offset and lv->length from the transaction
lock without bounds checking. When a corrupted JFS filesystem image
provides inconsistent dtree or xtree metadata, the transaction log
entries can reference slots beyond the root node boundaries
(DTROOTMAXSLOT or XTROOTMAXSLOT), causing a slab-out-of-bounds write
in the subsequent memcpy.
For example, with a crafted directory inode where the dtree metadata
produces lv->offset + lv->length > DTROOTMAXSLOT (9), the memcpy in
the dtree copy loop writes 32 bytes past the dinode boundary into
adjacent slab memory.
Add bounds validation before each memcpy in both the xtree and dtree
copy loops to ensure lv->offset + lv->length does not exceed
XTROOTMAXSLOT (18) or DTROOTMAXSLOT (9) respectively.
Reported-by: syzbot+aa6df9d3b383bf5f047f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=aa6df9d3b383bf5f047f
Tested-by: syzbot+aa6df9d3b383bf5f047f@syzkaller.appspotmail.com
Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
fs/jfs/jfs_imap.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index b84ba4d7dfb44..70d6a33597273 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -726,6 +726,11 @@ int diWrite(tid_t tid, struct inode *ip)
xp = &dp->di_xtroot;
lv = ilinelock->lv;
for (n = 0; n < ilinelock->index; n++, lv++) {
+ if (lv->offset + lv->length > XTROOTMAXSLOT) {
+ jfs_err("diWrite: xtree lv out of bounds");
+ release_metapage(mp);
+ return -EIO;
+ }
memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
lv->length << L2XTSLOTSIZE);
}
@@ -750,6 +755,11 @@ int diWrite(tid_t tid, struct inode *ip)
xp = (dtpage_t *) & dp->di_dtroot;
lv = ilinelock->lv;
for (n = 0; n < ilinelock->index; n++, lv++) {
+ if (lv->offset + lv->length > DTROOTMAXSLOT) {
+ jfs_err("diWrite: dtree lv out of bounds");
+ release_metapage(mp);
+ return -EIO;
+ }
memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
lv->length << L2DTSLOTSIZE);
}
--
2.47.3
reply other threads:[~2026-05-01 11:02 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=20260501110230.38407-1-tristmd@gmail.com \
--to=tristmd@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+aa6df9d3b383bf5f047f@syzkaller.appspotmail.com \
--cc=tristan@talencesecurity.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