Skip to content

Commit e9806ff

Browse files
committed
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
2 parents dc737f1 + a779ed7 commit e9806ff

File tree

7 files changed

+54
-29
lines changed

7 files changed

+54
-29
lines changed

fs/jfs/jfs_dinode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ struct dinode {
9696
#define di_gengen u._file._u1._imap._gengen
9797

9898
union {
99-
xtpage_t _xtroot;
99+
xtroot_t _xtroot;
100100
struct {
101101
u8 unused[16]; /* 16: */
102102
dxd_t _dxd; /* 16: */

fs/jfs/jfs_dmap.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno,
8787
static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
8888
static int dbFindBits(u32 word, int l2nb);
8989
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);
9191
static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
9292
int nblocks);
9393
static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap)
180180
bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
181181

182182
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) {
184185
err = -EINVAL;
185186
goto err_release_metapage;
186187
}
@@ -194,6 +195,12 @@ int dbMount(struct inode *ipbmap)
194195
bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
195196
bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
196197
bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
198+
if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 ||
199+
bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) {
200+
err = -EINVAL;
201+
goto err_release_metapage;
202+
}
203+
197204
bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
198205
bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
199206
bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
@@ -1710,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
17101717
* dbFindLeaf() returns the index of the leaf at which
17111718
* free space was found.
17121719
*/
1713-
rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx);
1720+
rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true);
17141721

17151722
/* release the buffer.
17161723
*/
@@ -1957,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp,
19571964
* free space. if sufficient free space is found, dbFindLeaf()
19581965
* returns the index of the leaf at which free space was found.
19591966
*/
1960-
if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
1967+
if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false))
19611968
return -ENOSPC;
19621969

19631970
if (leafidx < 0)
@@ -2921,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
29212928
* leafidx - return pointer to be set to the index of the leaf
29222929
* describing at least l2nb free blocks if sufficient
29232930
* free blocks are found.
2931+
* is_ctl - determines if the tree is of type ctl
29242932
*
29252933
* RETURN VALUES:
29262934
* 0 - success
29272935
* -ENOSPC - insufficient free blocks.
29282936
*/
2929-
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
2937+
static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)
29302938
{
29312939
int ti, n = 0, k, x = 0;
2940+
int max_size;
2941+
2942+
max_size = is_ctl ? CTLTREESIZE : TREESIZE;
29322943

29332944
/* first check the root of the tree to see if there is
29342945
* sufficient free space.
@@ -2949,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
29492960
/* sufficient free space found. move to the next
29502961
* level (or quit if this is the last level).
29512962
*/
2963+
if (x + n > max_size)
2964+
return -ENOSPC;
29522965
if (l2nb <= tp->dmt_stree[x + n])
29532966
break;
29542967
}

fs/jfs/jfs_imap.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ int diWrite(tid_t tid, struct inode *ip)
670670
* This is the special xtree inside the directory for storing
671671
* the directory table
672672
*/
673-
xtpage_t *p, *xp;
673+
xtroot_t *p, *xp;
674674
xad_t *xad;
675675

676676
jfs_ip->xtlid = 0;
@@ -684,7 +684,7 @@ int diWrite(tid_t tid, struct inode *ip)
684684
* copy xtree root from inode to dinode:
685685
*/
686686
p = &jfs_ip->i_xtroot;
687-
xp = (xtpage_t *) &dp->di_dirtable;
687+
xp = (xtroot_t *) &dp->di_dirtable;
688688
lv = ilinelock->lv;
689689
for (n = 0; n < ilinelock->index; n++, lv++) {
690690
memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
@@ -713,7 +713,7 @@ int diWrite(tid_t tid, struct inode *ip)
713713
* regular file: 16 byte (XAD slot) granularity
714714
*/
715715
if (type & tlckXTREE) {
716-
xtpage_t *p, *xp;
716+
xtroot_t *p, *xp;
717717
xad_t *xad;
718718

719719
/*
@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
13201320
int diAlloc(struct inode *pip, bool dir, struct inode *ip)
13211321
{
13221322
int rc, ino, iagno, addext, extno, bitno, sword;
1323-
int nwords, rem, i, agno;
1323+
int nwords, rem, i, agno, dn_numag;
13241324
u32 mask, inosmap, extsmap;
13251325
struct inode *ipimap;
13261326
struct metapage *mp;
@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
13561356

13571357
/* get the ag number of this iag */
13581358
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;
13591362

13601363
if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
13611364
/*

fs/jfs/jfs_incore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct jfs_inode_info {
6666
lid_t xtlid; /* lid of xtree lock on directory */
6767
union {
6868
struct {
69-
xtpage_t _xtroot; /* 288: xtree root */
69+
xtroot_t _xtroot; /* 288: xtree root */
7070
struct inomap *_imap; /* 4: inode map header */
7171
} file;
7272
struct {

fs/jfs/jfs_txnmgr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
783783
if (mp->xflag & COMMIT_PAGE)
784784
p = (xtpage_t *) mp->data;
785785
else
786-
p = &jfs_ip->i_xtroot;
786+
p = (xtpage_t *) &jfs_ip->i_xtroot;
787787
xtlck->lwm.offset =
788788
le16_to_cpu(p->header.nextindex);
789789
}
@@ -1676,7 +1676,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
16761676

16771677
if (tlck->type & tlckBTROOT) {
16781678
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;
16801680
if (S_ISDIR(ip->i_mode))
16811681
lrd->log.redopage.type |=
16821682
cpu_to_le16(LOG_DIR_XTREE);

fs/jfs/jfs_xtree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ xtSplitRoot(tid_t tid,
12131213
struct xtlock *xtlck;
12141214
int rc;
12151215

1216-
sp = &JFS_IP(ip)->i_xtroot;
1216+
sp = (xtpage_t *) &JFS_IP(ip)->i_xtroot;
12171217

12181218
INCREMENT(xtStat.split);
12191219

@@ -2098,7 +2098,7 @@ int xtAppend(tid_t tid, /* transaction id */
20982098
*/
20992099
void xtInitRoot(tid_t tid, struct inode *ip)
21002100
{
2101-
xtpage_t *p;
2101+
xtroot_t *p;
21022102

21032103
/*
21042104
* acquire a transaction lock on the root

fs/jfs/jfs_xtree.h

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,33 @@ struct xadlist {
6565
#define XTPAGEMAXSLOT 256
6666
#define XTENTRYSTART 2
6767

68-
/*
69-
* xtree page:
70-
*/
71-
typedef union {
72-
struct xtheader {
73-
__le64 next; /* 8: */
74-
__le64 prev; /* 8: */
68+
struct xtheader {
69+
__le64 next; /* 8: */
70+
__le64 prev; /* 8: */
7571

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: */
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: */
8177

82-
pxd_t self; /* 8: self */
83-
} header; /* (32) */
78+
pxd_t self; /* 8: self */
79+
};
8480

81+
/*
82+
* xtree root (in inode):
83+
*/
84+
typedef union {
85+
struct xtheader header;
8586
xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */
87+
} xtroot_t;
88+
89+
/*
90+
* xtree page:
91+
*/
92+
typedef union {
93+
struct xtheader header;
94+
xad_t xad[XTPAGEMAXSLOT]; /* 16 * maxentry: xad array */
8695
} xtpage_t;
8796

8897
/*

0 commit comments

Comments
 (0)