#syz test git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux-5.15.y
diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h
index 5fa9fd594115..e630810a48c6 100644
--- a/fs/jfs/jfs_dinode.h
+++ b/fs/jfs/jfs_dinode.h
@@ -96,7 +96,7 @@ struct dinode {
#define di_gengen u._file._u1._imap._gengen
union {
- xtpage_t _xtroot;
+ xtroot_t _xtroot;
struct {
u8 unused[16]; /* 16: */
dxd_t _dxd; /* 16: */
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 937ca07b58b1..5a360cd54098 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -671,7 +671,7 @@ int diWrite(tid_t tid, struct inode *ip)
* This is the special xtree inside the directory for storing
* the directory table
*/
- xtpage_t *p, *xp;
+ xtroot_t *p, *xp;
xad_t *xad;
jfs_ip->xtlid = 0;
@@ -685,7 +685,7 @@ int diWrite(tid_t tid, struct inode *ip)
* copy xtree root from inode to dinode:
*/
p = &jfs_ip->i_xtroot;
- xp = (xtpage_t *) &dp->di_dirtable;
+ xp = (xtroot_t *) &dp->di_dirtable;
lv = ilinelock->lv;
for (n = 0; n < ilinelock->index; n++, lv++) {
memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
@@ -714,7 +714,7 @@ int diWrite(tid_t tid, struct inode *ip)
* regular file: 16 byte (XAD slot) granularity
*/
if (type & tlckXTREE) {
- xtpage_t *p, *xp;
+ xtroot_t *p, *xp;
xad_t *xad;
/*
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index a466ec41cfbb..852f4c1f2946 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -66,7 +66,7 @@ struct jfs_inode_info {
lid_t xtlid; /* lid of xtree lock on directory */
union {
struct {
- xtpage_t _xtroot; /* 288: xtree root */
+ xtroot_t _xtroot; /* 288: xtree root */
struct inomap *_imap; /* 4: inode map header */
} file;
struct {
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index dca8edd2378c..7d19324f5a83 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -778,7 +778,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
if (mp->xflag & COMMIT_PAGE)
p = (xtpage_t *) mp->data;
else
- p = &jfs_ip->i_xtroot;
+ p = (xtpage_t *) &jfs_ip->i_xtroot;
xtlck->lwm.offset =
le16_to_cpu(p->header.nextindex);
}
@@ -1708,7 +1708,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
if (tlck->type & tlckBTROOT) {
lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
- p = &JFS_IP(ip)->i_xtroot;
+ p = (xtpage_t *) &JFS_IP(ip)->i_xtroot;
if (S_ISDIR(ip->i_mode))
lrd->log.redopage.type |=
cpu_to_le16(LOG_DIR_XTREE);
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index 3148e9b35f3b..34db519933b4 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -1224,7 +1224,7 @@ xtSplitRoot(tid_t tid,
struct xtlock *xtlck;
int rc;
- sp = &JFS_IP(ip)->i_xtroot;
+ sp = (xtpage_t *) &JFS_IP(ip)->i_xtroot;
INCREMENT(xtStat.split);
@@ -3059,7 +3059,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
*/
void xtInitRoot(tid_t tid, struct inode *ip)
{
- xtpage_t *p;
+ xtroot_t *p;
/*
* acquire a transaction lock on the root
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h
index 5f51be8596b3..dc9b5f8d6385 100644
--- a/fs/jfs/jfs_xtree.h
+++ b/fs/jfs/jfs_xtree.h
@@ -65,24 +65,33 @@ struct xadlist {
#define XTPAGEMAXSLOT 256
#define XTENTRYSTART 2
-/*
- * xtree page:
- */
-typedef union {
- struct xtheader {
- __le64 next; /* 8: */
- __le64 prev; /* 8: */
+struct xtheader {
+ __le64 next; /* 8: */
+ __le64 prev; /* 8: */
- u8 flag; /* 1: */
- u8 rsrvd1; /* 1: */
- __le16 nextindex; /* 2: next index = number of entries */
- __le16 maxentry; /* 2: max number of entries */
- __le16 rsrvd2; /* 2: */
+ u8 flag; /* 1: */
+ u8 rsrvd1; /* 1: */
+ __le16 nextindex; /* 2: next index = number of entries */
+ __le16 maxentry; /* 2: max number of entries */
+ __le16 rsrvd2; /* 2: */
- pxd_t self; /* 8: self */
- } header; /* (32) */
+ pxd_t self; /* 8: self */
+};
+/*
+ * xtree root (in inode):
+ */
+typedef union {
+ struct xtheader header;
xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */
+} xtroot_t;
+
+/*
+ * xtree page:
+ */
+typedef union {
+ struct xtheader header;
+ xad_t xad[XTPAGEMAXSLOT]; /* 16 * maxentry: xad array */
} xtpage_t;
/*
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
UBSAN: array-index-out-of-bounds in add_missing_indices
... Log Wrap ... Log Wrap ... Log Wrap ...
================================================================================
UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dtree.c:2946:28
index -128 is out of range for type 'struct dtslot[128]'
CPU: 0 PID: 5101 Comm: syz.0.16 Not tainted 5.15.180-syzkaller-07499-gf7347f400572-dirty #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
Call trace:
dump_backtrace+0x0/0x530 arch/arm64/kernel/stacktrace.c:152
show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:216
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0x108/0x170 lib/dump_stack.c:106
dump_stack+0x1c/0x58 lib/dump_stack.c:113
ubsan_epilogue lib/ubsan.c:151 [inline]
__ubsan_handle_out_of_bounds+0x108/0x15c lib/ubsan.c:282
add_missing_indices+0x6d0/0xaac fs/jfs/jfs_dtree.c:2946
jfs_readdir+0x1974/0x31dc fs/jfs/jfs_dtree.c:3316
iterate_dir+0x1f4/0x4ec fs/readdir.c:-1
__do_sys_getdents64 fs/readdir.c:369 [inline]
__se_sys_getdents64 fs/readdir.c:354 [inline]
__arm64_sys_getdents64+0x1c4/0x4c4 fs/readdir.c:354
__invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:52
el0_svc_common+0x138/0x258 arch/arm64/kernel/syscall.c:142
do_el0_svc+0x58/0x14c arch/arm64/kernel/syscall.c:181
el0_svc+0x7c/0x1f0 arch/arm64/kernel/entry-common.c:608
el0t_64_sync_handler+0x84/0xe4 arch/arm64/kernel/entry-common.c:626
el0t_64_sync+0x1a0/0x1a4 arch/arm64/kernel/entry.S:584
================================================================================
==================================================================
BUG: KASAN: slab-out-of-bounds in diWrite+0xb48/0x1604 fs/jfs/jfs_imap.c:753
Read of size 32 at addr ffffff80e16dc130 by task syz.0.16/5101
CPU: 1 PID: 5101 Comm: syz.0.16 Not tainted 5.15.180-syzkaller-07499-gf7347f400572-dirty #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
Call trace:
dump_backtrace+0x0/0x530 arch/arm64/kernel/stacktrace.c:152
show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:216
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0x108/0x170 lib/dump_stack.c:106
print_address_description+0x7c/0x3f0 mm/kasan/report.c:248
__kasan_report mm/kasan/report.c:434 [inline]
kasan_report+0x174/0x1e4 mm/kasan/report.c:451
check_region_inline mm/kasan/generic.c:-1 [inline]
kasan_check_range+0x274/0x2b4 mm/kasan/generic.c:189
memcpy+0x90/0xe8 mm/kasan/shadow.c:65
diWrite+0xb48/0x1604 fs/jfs/jfs_imap.c:753
txCommit+0x748/0x5548 fs/jfs/jfs_txnmgr.c:1255
add_missing_indices+0x74c/0xaac fs/jfs/jfs_dtree.c:2960
jfs_readdir+0x1974/0x31dc fs/jfs/jfs_dtree.c:3316
iterate_dir+0x1f4/0x4ec fs/readdir.c:-1
__do_sys_getdents64 fs/readdir.c:369 [inline]
__se_sys_getdents64 fs/readdir.c:354 [inline]
__arm64_sys_getdents64+0x1c4/0x4c4 fs/readdir.c:354
__invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:52
el0_svc_common+0x138/0x258 arch/arm64/kernel/syscall.c:142
do_el0_svc+0x58/0x14c arch/arm64/kernel/syscall.c:181
el0_svc+0x7c/0x1f0 arch/arm64/kernel/entry-common.c:608
el0t_64_sync_handler+0x84/0xe4 arch/arm64/kernel/entry-common.c:626
el0t_64_sync+0x1a0/0x1a4 arch/arm64/kernel/entry.S:584
Allocated by task 0:
(stack is not available)
The buggy address belongs to the object at ffffff80e16dc0c0
which belongs to the cache jfs_ip of size 2240
The buggy address is located 112 bytes inside of
2240-byte region [ffffff80e16dc0c0, ffffff80e16dc980)
The buggy address belongs to the page:
page:0000000001ce143c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1216d8
head:0000000001ce143c order:3 compound_mapcount:0 compound_pincount:0
memcg:ffffff80e68fcb01
flags: 0x5ffc00000010200(slab|head|node=0|zone=2|lastcpupid=0x7ff)
raw: 05ffc00000010200 0000000000000000 dead000000000122 ffffff80c2b8ea80
raw: 0000000000000000 00000000800d000d 00000001ffffffff ffffff80e68fcb01
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffffff80e16dc000: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc
ffffff80e16dc080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffffff80e16dc100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffffff80e16dc180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffffff80e16dc200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
... Log Wrap ... Log Wrap ... Log Wrap ...
... Log Wrap ... Log Wrap ... Log Wrap ...
... Log Wrap ... Log Wrap ... Log Wrap ...
ERROR: (device loop0): jfs_readdir: JFS:Dtree error: ino = 2, bn=0, index = 0
ERROR: (device loop0): remounting filesystem as read-only
JFS: Invalid stbl[1] = -128 for inode 2, block = 0
Tested on:
commit: f7347f40 Linux 5.15.180
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux-5.15.y
console output: https://syzkaller.appspot.com/x/log.txt?x=163c0204580000
kernel config: https://syzkaller.appspot.com/x/.config?x=e433a356d25f60cb
dashboard link: https://syzkaller.appspot.com/bug?extid=b974bd41515f770c608b
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64
patch: https://syzkaller.appspot.com/x/patch.diff?x=135bfc04580000
© 2016 - 2026 Red Hat, Inc.