[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20260112122212.7133-1-xqzmiplz@yandex.ru>
Date: Mon, 12 Jan 2026 15:22:12 +0300
From: Vadim Havkin <xqzmiplz@...dex.ru>
To: shaggy@...nel.org
Cc: jfs-discussion@...ts.sourceforge.net,
linux-kernel@...r.kernel.org,
lvc-project@...uxtesting.org
Subject: [PATCH] jfs: fix slab-out-of-bounds read in dtSearch
Syzkaller reported a slab-out-of-bounds read in dtSearch. This occurs
when the driver attempts to access the slot array using an index read
from the stbl (sorted table) without validation.
When working with an inline directory (bn == 0), the p pointer refers
to the dtroot_t structure embedded in jfs_inode_info. This buffer can
hold DTROOTMAXSLOT slots. However, the pointer is cast to (dtpage_t *),
which corresponds to a full page (DTPAGEMAXSLOT slots). If a corrupted
image contains an index in stbl greater than or equal to DTROOTMAXSLOT,
the driver calculates an address outside the allocated slab object.
BUG: KASAN: slab-out-of-bounds in dtSearch+0x21fd/0x2270 fs/jfs/jfs_dtree.c:645
Read of size 1 at addr ffff88810d94b5d4 by task syz-executor107/859
Call Trace:
<TASK>
kasan_report+0xb9/0xf0
dtSearch+0x21fd/0x2270
jfs_lookup+0x180/0x340
lookup_open.isra.0+0x7a7/0x1430
path_openat+0xcc0/0x2960
do_filp_open+0x1c3/0x410
do_sys_openat2+0x164/0x1d0
__x64_sys_openat+0x13c/0x1f0
</TASK>
Add a check to ensure that the index read from stbl is valid.
For the inline root (bn == 0), the index must be strictly less than
DTROOTMAXSLOT. Note that stbl values are type s8, so they cannot
exceed the external page limit (DTPAGEMAXSLOT = 128).
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Vadim Havkin <xqzmiplz@...dex.ru>
---
fs/jfs/jfs_dtree.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 93db6eec4465..d2bdadaf4672 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -634,7 +634,8 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) {
index = base + (lim >> 1);
- if (stbl[index] < 0) {
+ if (stbl[index] < 0 ||
+ (bn == 0 && stbl[index] >= DTROOTMAXSLOT)) {
rc = -EIO;
goto out;
}
--
2.43.0
Powered by blists - more mailing lists