From: Dave Kleikamp dave.kleikamp@oracle.com
[ Upstream commit a779ed754e52d582b8c0e17959df063108bd0656 ]
In order to make array bounds checking sane, provide a separate definition of the in-inode xtree root and the external xtree page.
Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Tested-by: Manas Ghandat ghandatmanas@gmail.com (cherry picked from commit a779ed754e52d582b8c0e17959df063108bd0656) Closes: https://syzkaller.appspot.com/bug?extid=ccb458b6679845ee0bae Signed-off-by: Aditya Dutt duttaditya18@gmail.com --- Tested using C reproducer here: https://syzkaller.appspot.com/x/repro.c?x=113bb250e80000 (given in the dashboard link above UBSAN is not triggered when this commit is there. It is triggered when it is not.
fs/jfs/jfs_dinode.h | 2 +- fs/jfs/jfs_imap.c | 6 +++--- fs/jfs/jfs_incore.h | 2 +- fs/jfs/jfs_txnmgr.c | 4 ++-- fs/jfs/jfs_xtree.c | 4 ++-- fs/jfs/jfs_xtree.h | 37 +++++++++++++++++++++++-------------- 6 files changed, 32 insertions(+), 23 deletions(-)
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;
/*
syzbot checked the patch against 5.15.y and confirmed that the reproducer did not trigger any issues. check here: https://lore.kernel.org/lkml/67fea0bf.050a0220.186b78.0006.GAE@google.com/
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: a779ed754e52d582b8c0e17959df063108bd0656
WARNING: Author mismatch between patch and upstream commit: Backport author: Aditya Duttduttaditya18@gmail.com Commit author: Dave Kleikampdave.kleikamp@oracle.com
Status in newer kernel trees: 6.14.y | Present (exact SHA1) 6.13.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (different SHA1: 2ff51719ec61) 6.1.y | Not found
Note: The patch differs from the upstream commit: --- 1: a779ed754e52d ! 1: aaa01b34169c0 jfs: define xtree root and page independently @@ Metadata ## Commit message ## jfs: define xtree root and page independently
+ [ Upstream commit a779ed754e52d582b8c0e17959df063108bd0656 ] + In order to make array bounds checking sane, provide a separate definition of the in-inode xtree root and the external xtree page.
Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Tested-by: Manas Ghandat ghandatmanas@gmail.com + (cherry picked from commit a779ed754e52d582b8c0e17959df063108bd0656) + Closes: https://syzkaller.appspot.com/bug?extid=ccb458b6679845ee0bae + Signed-off-by: Aditya Dutt duttaditya18@gmail.com
## fs/jfs/jfs_dinode.h ## @@ fs/jfs/jfs_dinode.h: struct dinode { @@ fs/jfs/jfs_xtree.c: xtSplitRoot(tid_t tid,
INCREMENT(xtStat.split);
-@@ fs/jfs/jfs_xtree.c: int xtAppend(tid_t tid, /* transaction id */ +@@ fs/jfs/jfs_xtree.c: static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p) */ void xtInitRoot(tid_t tid, struct inode *ip) { ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |
On Tue, Apr 15, 2025 at 11:39:39PM +0530, Aditya Dutt wrote:
From: Dave Kleikamp dave.kleikamp@oracle.com
[ Upstream commit a779ed754e52d582b8c0e17959df063108bd0656 ]
In order to make array bounds checking sane, provide a separate definition of the in-inode xtree root and the external xtree page.
Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Tested-by: Manas Ghandat ghandatmanas@gmail.com (cherry picked from commit a779ed754e52d582b8c0e17959df063108bd0656) Closes: https://syzkaller.appspot.com/bug?extid=ccb458b6679845ee0bae Signed-off-by: Aditya Dutt duttaditya18@gmail.com
Tested using C reproducer here: https://syzkaller.appspot.com/x/repro.c?x=113bb250e80000 (given in the dashboard link above UBSAN is not triggered when this commit is there. It is triggered when it is not.
Please always submit backports for all relevant stable trees. We can't take this one until the newer trees are fixed.
Please resubmit all ones needed.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org