mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
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()
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"); \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
jfs_ip->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 = fileset;
|
||||
jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
|
||||
jfs_set_inode_flags(ip);
|
||||
|
||||
|
||||
@@ -389,8 +389,8 @@ static int jfs_reconfigure(struct fs_context *fc)
|
||||
|
||||
if (!ctx->newLVSize) {
|
||||
ctx->newLVSize = sb_bdev_nr_blocks(sb);
|
||||
if (ctx->newLVSize == 0)
|
||||
pr_err("JFS: Cannot determine volume size\n");
|
||||
if (ctx->newLVSize == 0)
|
||||
pr_err("JFS: Cannot determine volume size\n");
|
||||
}
|
||||
|
||||
rc = jfs_extendfs(sb, ctx->newLVSize, 0);
|
||||
@@ -766,7 +766,7 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type,
|
||||
}
|
||||
lock_buffer(bh);
|
||||
memcpy(bh->b_data+offset, data, tocopy);
|
||||
flush_dcache_page(bh->b_page);
|
||||
flush_dcache_folio(bh->b_folio);
|
||||
set_buffer_uptodate(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
unlock_buffer(bh);
|
||||
|
||||
@@ -559,11 +559,16 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
|
||||
|
||||
size_check:
|
||||
if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
|
||||
int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
|
||||
if (unlikely(EALIST_SIZE(ea_buf->xattr) > INT_MAX)) {
|
||||
printk(KERN_ERR "ea_get: extended attribute size too large: %u > INT_MAX\n",
|
||||
EALIST_SIZE(ea_buf->xattr));
|
||||
} else {
|
||||
int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
|
||||
|
||||
printk(KERN_ERR "ea_get: invalid extended attribute\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
|
||||
ea_buf->xattr, size, 1);
|
||||
printk(KERN_ERR "ea_get: invalid extended attribute\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
|
||||
ea_buf->xattr, size, 1);
|
||||
}
|
||||
ea_release(inode, ea_buf);
|
||||
rc = -EIO;
|
||||
goto clean_up;
|
||||
|
||||
Reference in New Issue
Block a user