Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'jfs-6.7' of https://github.com/kleikamp/linux-shaggy

Pull jfs updates from Dave Kleikamp:
"Minor stability improvements"

* tag 'jfs-6.7' of https://github.com/kleikamp/linux-shaggy:
jfs: define xtree root and page independently
jfs: fix array-index-out-of-bounds in diAlloc
jfs: fix array-index-out-of-bounds in dbFindLeaf
fs/jfs: Add validity check for db_maxag and db_agpref
fs/jfs: Add check for negative db_l2nbperpage

+54 -29
+1 -1
fs/jfs/jfs_dinode.h
··· 96 96 #define di_gengen u._file._u1._imap._gengen 97 97 98 98 union { 99 - xtpage_t _xtroot; 99 + xtroot_t _xtroot; 100 100 struct { 101 101 u8 unused[16]; /* 16: */ 102 102 dxd_t _dxd; /* 16: */
+18 -5
fs/jfs/jfs_dmap.c
··· 87 87 static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); 88 88 static int dbFindBits(u32 word, int l2nb); 89 89 static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); 90 - static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); 90 + static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl); 91 91 static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, 92 92 int nblocks); 93 93 static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, ··· 180 180 bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); 181 181 182 182 bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); 183 - if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { 183 + if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE || 184 + bmp->db_l2nbperpage < 0) { 184 185 err = -EINVAL; 185 186 goto err_release_metapage; 186 187 } ··· 195 194 bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); 196 195 bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); 197 196 bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); 197 + if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 || 198 + bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) { 199 + err = -EINVAL; 200 + goto err_release_metapage; 201 + } 202 + 198 203 bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); 199 204 bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); 200 205 bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); ··· 1717 1710 * dbFindLeaf() returns the index of the leaf at which 1718 1711 * free space was found. 1719 1712 */ 1720 - rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx); 1713 + rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true); 1721 1714 1722 1715 /* release the buffer. 1723 1716 */ ··· 1964 1957 * free space. if sufficient free space is found, dbFindLeaf() 1965 1958 * returns the index of the leaf at which free space was found. 1966 1959 */ 1967 - if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) 1960 + if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false)) 1968 1961 return -ENOSPC; 1969 1962 1970 1963 if (leafidx < 0) ··· 2928 2921 * leafidx - return pointer to be set to the index of the leaf 2929 2922 * describing at least l2nb free blocks if sufficient 2930 2923 * free blocks are found. 2924 + * is_ctl - determines if the tree is of type ctl 2931 2925 * 2932 2926 * RETURN VALUES: 2933 2927 * 0 - success 2934 2928 * -ENOSPC - insufficient free blocks. 2935 2929 */ 2936 - static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) 2930 + static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl) 2937 2931 { 2938 2932 int ti, n = 0, k, x = 0; 2933 + int max_size; 2934 + 2935 + max_size = is_ctl ? CTLTREESIZE : TREESIZE; 2939 2936 2940 2937 /* first check the root of the tree to see if there is 2941 2938 * sufficient free space. ··· 2960 2949 /* sufficient free space found. move to the next 2961 2950 * level (or quit if this is the last level). 2962 2951 */ 2952 + if (x + n > max_size) 2953 + return -ENOSPC; 2963 2954 if (l2nb <= tp->dmt_stree[x + n]) 2964 2955 break; 2965 2956 }
+7 -4
fs/jfs/jfs_imap.c
··· 670 670 * This is the special xtree inside the directory for storing 671 671 * the directory table 672 672 */ 673 - xtpage_t *p, *xp; 673 + xtroot_t *p, *xp; 674 674 xad_t *xad; 675 675 676 676 jfs_ip->xtlid = 0; ··· 684 684 * copy xtree root from inode to dinode: 685 685 */ 686 686 p = &jfs_ip->i_xtroot; 687 - xp = (xtpage_t *) &dp->di_dirtable; 687 + xp = (xtroot_t *) &dp->di_dirtable; 688 688 lv = ilinelock->lv; 689 689 for (n = 0; n < ilinelock->index; n++, lv++) { 690 690 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset], ··· 713 713 * regular file: 16 byte (XAD slot) granularity 714 714 */ 715 715 if (type & tlckXTREE) { 716 - xtpage_t *p, *xp; 716 + xtroot_t *p, *xp; 717 717 xad_t *xad; 718 718 719 719 /* ··· 1320 1320 int diAlloc(struct inode *pip, bool dir, struct inode *ip) 1321 1321 { 1322 1322 int rc, ino, iagno, addext, extno, bitno, sword; 1323 - int nwords, rem, i, agno; 1323 + int nwords, rem, i, agno, dn_numag; 1324 1324 u32 mask, inosmap, extsmap; 1325 1325 struct inode *ipimap; 1326 1326 struct metapage *mp; ··· 1356 1356 1357 1357 /* get the ag number of this iag */ 1358 1358 agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); 1359 + dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag; 1360 + if (agno < 0 || agno > dn_numag) 1361 + return -EIO; 1359 1362 1360 1363 if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { 1361 1364 /*
+1 -1
fs/jfs/jfs_incore.h
··· 66 66 lid_t xtlid; /* lid of xtree lock on directory */ 67 67 union { 68 68 struct { 69 - xtpage_t _xtroot; /* 288: xtree root */ 69 + xtroot_t _xtroot; /* 288: xtree root */ 70 70 struct inomap *_imap; /* 4: inode map header */ 71 71 } file; 72 72 struct {
+2 -2
fs/jfs/jfs_txnmgr.c
··· 783 783 if (mp->xflag & COMMIT_PAGE) 784 784 p = (xtpage_t *) mp->data; 785 785 else 786 - p = &jfs_ip->i_xtroot; 786 + p = (xtpage_t *) &jfs_ip->i_xtroot; 787 787 xtlck->lwm.offset = 788 788 le16_to_cpu(p->header.nextindex); 789 789 } ··· 1676 1676 1677 1677 if (tlck->type & tlckBTROOT) { 1678 1678 lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); 1679 - p = &JFS_IP(ip)->i_xtroot; 1679 + p = (xtpage_t *) &JFS_IP(ip)->i_xtroot; 1680 1680 if (S_ISDIR(ip->i_mode)) 1681 1681 lrd->log.redopage.type |= 1682 1682 cpu_to_le16(LOG_DIR_XTREE);
+2 -2
fs/jfs/jfs_xtree.c
··· 1213 1213 struct xtlock *xtlck; 1214 1214 int rc; 1215 1215 1216 - sp = &JFS_IP(ip)->i_xtroot; 1216 + sp = (xtpage_t *) &JFS_IP(ip)->i_xtroot; 1217 1217 1218 1218 INCREMENT(xtStat.split); 1219 1219 ··· 2098 2098 */ 2099 2099 void xtInitRoot(tid_t tid, struct inode *ip) 2100 2100 { 2101 - xtpage_t *p; 2101 + xtroot_t *p; 2102 2102 2103 2103 /* 2104 2104 * acquire a transaction lock on the root
+23 -14
fs/jfs/jfs_xtree.h
··· 65 65 #define XTPAGEMAXSLOT 256 66 66 #define XTENTRYSTART 2 67 67 68 + struct xtheader { 69 + __le64 next; /* 8: */ 70 + __le64 prev; /* 8: */ 71 + 72 + u8 flag; /* 1: */ 73 + u8 rsrvd1; /* 1: */ 74 + __le16 nextindex; /* 2: next index = number of entries */ 75 + __le16 maxentry; /* 2: max number of entries */ 76 + __le16 rsrvd2; /* 2: */ 77 + 78 + pxd_t self; /* 8: self */ 79 + }; 80 + 81 + /* 82 + * xtree root (in inode): 83 + */ 84 + typedef union { 85 + struct xtheader header; 86 + xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */ 87 + } xtroot_t; 88 + 68 89 /* 69 90 * xtree page: 70 91 */ 71 92 typedef union { 72 - struct xtheader { 73 - __le64 next; /* 8: */ 74 - __le64 prev; /* 8: */ 75 - 76 - u8 flag; /* 1: */ 77 - u8 rsrvd1; /* 1: */ 78 - __le16 nextindex; /* 2: next index = number of entries */ 79 - __le16 maxentry; /* 2: max number of entries */ 80 - __le16 rsrvd2; /* 2: */ 81 - 82 - pxd_t self; /* 8: self */ 83 - } header; /* (32) */ 84 - 85 - xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */ 93 + struct xtheader header; 94 + xad_t xad[XTPAGEMAXSLOT]; /* 16 * maxentry: xad array */ 86 95 } xtpage_t; 87 96 88 97 /*