Commit 61d5f629 authored by Manas Ghandat's avatar Manas Ghandat Committed by Long Li
Browse files

jfs: fix array-index-out-of-bounds in dbFindLeaf

stable inclusion
from stable-v5.10.201
commit 81aa58cd8495b8c3b527f58ccbe19478d8087f61
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9REBH
CVE: CVE-2023-52799

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=tags/v5.10.202&id=81aa58cd8495b8c3b527f58ccbe19478d8087f61



--------------------------------

[ Upstream commit 22cad8bc1d36547cdae0eef316c47d917ce3147c ]

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: default avatar <syzbot+aea1ad91e854d0a83e04@syzkaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=aea1ad91e854d0a83e04


Signed-off-by: default avatarManas Ghandat <ghandatmanas@gmail.com>
Signed-off-by: default avatarDave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
parent 9faf865d
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno,
static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
static int dbFindBits(u32 word, int l2nb);
static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl);
static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
		      int nblocks);
static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
@@ -1771,7 +1771,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
		 * dbFindLeaf() returns the index of the leaf at which
		 * free space was found.
		 */
		rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx);
		rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true);

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

	if (leafidx < 0)
@@ -2983,14 +2983,18 @@ static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl)
 *	leafidx	- return pointer to be set to the index of the leaf
 *		  describing at least l2nb free blocks if sufficient
 *		  free blocks are found.
 *	is_ctl	- determines if the tree is of type ctl
 *
 * RETURN VALUES:
 *	0	- success
 *	-ENOSPC	- insufficient free blocks.
 */
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)
{
	int ti, n = 0, k, x = 0;
	int max_size;

	max_size = is_ctl ? CTLTREESIZE : TREESIZE;

	/* first check the root of the tree to see if there is
	 * sufficient free space.
@@ -3011,6 +3015,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
			/* sufficient free space found.  move to the next
			 * level (or quit if this is the last level).
			 */
			if (x + n > max_size)
				return -ENOSPC;
			if (l2nb <= tp->dmt_stree[x + n])
				break;
		}