Skip to content

Commit 22cad8b

Browse files
manasghandatkleikamp
authored andcommitted
jfs: fix array-index-out-of-bounds in dbFindLeaf
Currently while searching for dmtree_t for sufficient free blocks there is an array out of bounds while getting element in tp->dm_stree. To add the required check for out of bound we first need to determine the type of dmtree. Thus added an extra parameter to dbFindLeaf so that the type of tree can be determined and the required check can be applied. Reported-by: [email protected] Closes: https://syzkaller.appspot.com/bug?extid=aea1ad91e854d0a83e04 Signed-off-by: Manas Ghandat <[email protected]> Signed-off-by: Dave Kleikamp <[email protected]>
1 parent 64933ab commit 22cad8b

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

fs/jfs/jfs_dmap.c

Lines changed: 10 additions & 4 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,
@@ -1717,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
17171717
* dbFindLeaf() returns the index of the leaf at which
17181718
* free space was found.
17191719
*/
1720-
rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx);
1720+
rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true);
17211721

17221722
/* release the buffer.
17231723
*/
@@ -1964,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp,
19641964
* free space. if sufficient free space is found, dbFindLeaf()
19651965
* returns the index of the leaf at which free space was found.
19661966
*/
1967-
if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
1967+
if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false))
19681968
return -ENOSPC;
19691969

19701970
if (leafidx < 0)
@@ -2928,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
29282928
* leafidx - return pointer to be set to the index of the leaf
29292929
* describing at least l2nb free blocks if sufficient
29302930
* free blocks are found.
2931+
* is_ctl - determines if the tree is of type ctl
29312932
*
29322933
* RETURN VALUES:
29332934
* 0 - success
29342935
* -ENOSPC - insufficient free blocks.
29352936
*/
2936-
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
2937+
static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)
29372938
{
29382939
int ti, n = 0, k, x = 0;
2940+
int max_size;
2941+
2942+
max_size = is_ctl ? CTLTREESIZE : TREESIZE;
29392943

29402944
/* first check the root of the tree to see if there is
29412945
* sufficient free space.
@@ -2956,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
29562960
/* sufficient free space found. move to the next
29572961
* level (or quit if this is the last level).
29582962
*/
2963+
if (x + n > max_size)
2964+
return -ENOSPC;
29592965
if (l2nb <= tp->dmt_stree[x + n])
29602966
break;
29612967
}

0 commit comments

Comments
 (0)