Skip to content

Commit

Permalink
fs: jfs: fix shift-out-of-bounds in dbAllocAG
Browse files Browse the repository at this point in the history
[ Upstream commit 898f706 ]

Syzbot found a crash : UBSAN: shift-out-of-bounds in dbAllocAG. The
underlying bug is the missing check of bmp->db_agl2size. The field can
be greater than 64 and trigger the shift-out-of-bounds.

Fix this bug by adding a check of bmp->db_agl2size in dbMount since this
field is used in many following functions. The upper bound for this
field is L2MAXL2SIZE - L2MAXAG, thanks for the help of Dave Kleikamp.
Note that, for maintenance, I reorganized error handling code of dbMount.

Reported-by: syzbot+15342c1aa6a00fb7a438@syzkaller.appspotmail.com
Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
mudongliang authored and gregkh committed Dec 31, 2022
1 parent aaf8770 commit 67973ca
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions fs/jfs/jfs_dmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ int dbMount(struct inode *ipbmap)
struct bmap *bmp;
struct dbmap_disk *dbmp_le;
struct metapage *mp;
int i;
int i, err;

/*
* allocate/initialize the in-memory bmap descriptor
Expand All @@ -170,8 +170,8 @@ int dbMount(struct inode *ipbmap)
BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
PSIZE, 0);
if (mp == NULL) {
kfree(bmp);
return -EIO;
err = -EIO;
goto err_kfree_bmp;
}

/* copy the on-disk bmap descriptor to its in-memory version. */
Expand All @@ -181,9 +181,8 @@ int dbMount(struct inode *ipbmap)
bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
if (!bmp->db_numag) {
release_metapage(mp);
kfree(bmp);
return -EINVAL;
err = -EINVAL;
goto err_release_metapage;
}

bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
Expand All @@ -194,6 +193,11 @@ int dbMount(struct inode *ipbmap)
bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) {
err = -EINVAL;
goto err_release_metapage;
}

for (i = 0; i < MAXAG; i++)
bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
Expand All @@ -214,6 +218,12 @@ int dbMount(struct inode *ipbmap)
BMAP_LOCK_INIT(bmp);

return (0);

err_release_metapage:
release_metapage(mp);
err_kfree_bmp:
kfree(bmp);
return err;
}


Expand Down

0 comments on commit 67973ca

Please sign in to comment.