Commit f79adee8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull jfs updates from David Kleikamp:
 "Various bug fixes and cleanups for JFS"

* tag 'jfs-6.14' of github.com:kleikamp/linux-shaggy:
  jfs: add index corruption check to DT_GETPAGE()
  fs/jfs: consolidate sanity checking in dbMount
  jfs: add sanity check for agwidth in dbMount
  jfs: Prevent copying of nlink with value 0 from disk inode
  fs/jfs: Prevent integer overflow in AG size calculation
  fs/jfs: cast inactags to s64 to prevent potential overflow
  jfs: Fix uninit-value access of imap allocated in the diMount() function
  jfs: fix slab-out-of-bounds read in ea_get()
  jfs: add check read-only before truncation in jfs_truncate_nolock()
  jfs: add check read-only before txBeginAnon() call
  jfs: reject on-disk inodes of an unsupported type
  jfs: Remove reference to bh->b_page
  jfs: Delete a couple tabs in jfs_reconfigure()
parents fde05627 a8dfb216
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)

	ASSERT(length >= 0);

	if (test_cflag(COMMIT_Nolink, ip)) {
	if (test_cflag(COMMIT_Nolink, ip) || isReadOnly(ip)) {
		xtTruncate(0, ip, length, COMMIT_WMAP);
		return;
	}
+12 −27
Original line number Diff line number Diff line
@@ -178,41 +178,26 @@ int dbMount(struct inode *ipbmap)
	dbmp_le = (struct dbmap_disk *) mp->data;
	bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
	bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);

	bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
	if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE ||
		bmp->db_l2nbperpage < 0) {
		err = -EINVAL;
		goto err_release_metapage;
	}

	bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
	if (!bmp->db_numag || bmp->db_numag > MAXAG) {
		err = -EINVAL;
		goto err_release_metapage;
	}

	bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
	bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
	bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
	if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 ||
		bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) {
		err = -EINVAL;
		goto err_release_metapage;
	}

	bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
	bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
	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 ||
	    bmp->db_agl2size < 0) {
		err = -EINVAL;
		goto err_release_metapage;
	}

	if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
	if ((bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) ||
	    (bmp->db_l2nbperpage < 0) ||
	    !bmp->db_numag || (bmp->db_numag > MAXAG) ||
	    (bmp->db_maxag >= MAXAG) || (bmp->db_maxag < 0) ||
	    (bmp->db_agpref >= MAXAG) || (bmp->db_agpref < 0) ||
	    !bmp->db_agwidth ||
	    (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) ||
	    (bmp->db_agl2size < 0) ||
	    ((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
		err = -EINVAL;
		goto err_release_metapage;
	}
@@ -3403,7 +3388,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
	oldl2agsize = bmp->db_agl2size;

	bmp->db_agl2size = l2agsize;
	bmp->db_agsize = 1 << l2agsize;
	bmp->db_agsize = (s64)1 << l2agsize;

	/* compute new number of AG */
	agno = bmp->db_numag;
@@ -3666,8 +3651,8 @@ void dbFinalizeBmap(struct inode *ipbmap)
	 * system size is not a multiple of the group size).
	 */
	inactfree = (inactags && ag_rem) ?
	    ((inactags - 1) << bmp->db_agl2size) + ag_rem
	    : inactags << bmp->db_agl2size;
	    (((s64)inactags - 1) << bmp->db_agl2size) + ag_rem
	    : ((s64)inactags << bmp->db_agl2size);

	/* determine how many free blocks are in the active
	 * allocation groups plus the average number of free blocks
+2 −1
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ do { \
	if (!(RC)) {							\
		if (((P)->header.nextindex >				\
		     (((BN) == 0) ? DTROOTMAXSLOT : (P)->header.maxslot)) || \
		    ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT))) {	\
		    ((BN) && (((P)->header.maxslot > DTPAGEMAXSLOT) ||	\
		    ((P)->header.stblindex >= DTPAGEMAXSLOT)))) {	\
			BT_PUTPAGE(MP);					\
			jfs_error((IP)->i_sb,				\
				  "DT_GETPAGE: dtree page corrupt\n");	\
+10 −0
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
	int rc;
	int xflag;

	if (isReadOnly(ip)) {
		jfs_error(ip->i_sb, "read-only filesystem\n");
		return -EIO;
	}

	/* This blocks if we are low on resources */
	txBeginAnon(ip->i_sb);

@@ -253,6 +258,11 @@ int extRecord(struct inode *ip, xad_t * xp)
{
	int rc;

	if (isReadOnly(ip)) {
		jfs_error(ip->i_sb, "read-only filesystem\n");
		return -EIO;
	}

	txBeginAnon(ip->i_sb);

	mutex_lock(&JFS_IP(ip)->commit_mutex);
+13 −4
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ int diMount(struct inode *ipimap)
	 * allocate/initialize the in-memory inode map control structure
	 */
	/* allocate the in-memory inode map control structure. */
	imap = kmalloc(sizeof(struct inomap), GFP_KERNEL);
	imap = kzalloc(sizeof(struct inomap), GFP_KERNEL);
	if (imap == NULL)
		return -ENOMEM;

@@ -456,7 +456,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
	dp += inum % 8;		/* 8 inodes per 4K page */

	/* copy on-disk inode to in-memory inode */
	if ((copy_from_dinode(dp, ip)) != 0) {
	if ((copy_from_dinode(dp, ip) != 0) || (ip->i_nlink == 0)) {
		/* handle bad return by returning NULL for ip */
		set_nlink(ip, 1);	/* Don't want iput() deleting it */
		iput(ip);
@@ -3029,14 +3029,23 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
 *
 * RETURN VALUES:
 *	0	- success
 *	-ENOMEM	- insufficient memory
 *	-EINVAL	- unexpected inode type
 */
static int copy_from_dinode(struct dinode * dip, struct inode *ip)
{
	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
	int fileset = le32_to_cpu(dip->di_fileset);

	switch (fileset) {
	case AGGR_RESERVED_I: case AGGREGATE_I: case BMAP_I:
	case LOG_I: case BADBLOCK_I: case FILESYSTEM_I:
		break;
	default:
		return -EINVAL;
	}

	jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
	jfs_ip->fileset = fileset;
	jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
	jfs_set_inode_flags(ip);

Loading