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 |
linux-stable-mirror@lists.linaro.org