ocfs2: fix crash when mount with quota enabled
There is a reported crash when mounting ocfs2 with quota enabled. RIP: 0010:ocfs2_qinfo_lock_res_init+0x44/0x50 [ocfs2] Call Trace: ocfs2_local_read_info+0xb9/0x6f0 [ocfs2] dquot_load_quota_sb+0x216/0x470 dquot_load_quota_inode+0x85/0x100 ocfs2_enable_quotas+0xa0/0x1c0 [ocfs2] ocfs2_fill_super.cold+0xc8/0x1bf [ocfs2] mount_bdev+0x185/0x1b0 legacy_get_tree+0x27/0x40 vfs_get_tree+0x25/0xb0 path_mount+0x465/0xac0 __x64_sys_mount+0x103/0x140 It is caused by when initializing dqi_gqlock, the corresponding dqi_type and dqi_sb are not properly initialized. This issue is introduced by commit6c85c2c728
, which wants to avoid accessing uninitialized variables in error cases. So make global quota info properly initialized. Link: https://lkml.kernel.org/r/20220323023644.40084-1-joseph.qi@linux.alibaba.com Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1007141 Fixes:6c85c2c728
("ocfs2: quota_local: fix possible uninitialized-variable access in ocfs2_local_read_info()") Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com> Reported-by: Dayvison <sathlerds@gmail.com> Tested-by: Valentin Vidic <vvidic@valentin-vidic.from.hr> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
e6b0a7b357
commit
de19433423
|
@ -337,7 +337,6 @@ void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex)
|
|||
/* Read information header from global quota file */
|
||||
int ocfs2_global_read_info(struct super_block *sb, int type)
|
||||
{
|
||||
struct inode *gqinode = NULL;
|
||||
unsigned int ino[OCFS2_MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
|
||||
GROUP_QUOTA_SYSTEM_INODE };
|
||||
struct ocfs2_global_disk_dqinfo dinfo;
|
||||
|
@ -346,29 +345,31 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
|
|||
u64 pcount;
|
||||
int status;
|
||||
|
||||
oinfo->dqi_gi.dqi_sb = sb;
|
||||
oinfo->dqi_gi.dqi_type = type;
|
||||
ocfs2_qinfo_lock_res_init(&oinfo->dqi_gqlock, oinfo);
|
||||
oinfo->dqi_gi.dqi_entry_size = sizeof(struct ocfs2_global_disk_dqblk);
|
||||
oinfo->dqi_gi.dqi_ops = &ocfs2_global_ops;
|
||||
oinfo->dqi_gqi_bh = NULL;
|
||||
oinfo->dqi_gqi_count = 0;
|
||||
|
||||
/* Read global header */
|
||||
gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
|
||||
oinfo->dqi_gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
|
||||
OCFS2_INVALID_SLOT);
|
||||
if (!gqinode) {
|
||||
if (!oinfo->dqi_gqinode) {
|
||||
mlog(ML_ERROR, "failed to get global quota inode (type=%d)\n",
|
||||
type);
|
||||
status = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
oinfo->dqi_gi.dqi_sb = sb;
|
||||
oinfo->dqi_gi.dqi_type = type;
|
||||
oinfo->dqi_gi.dqi_entry_size = sizeof(struct ocfs2_global_disk_dqblk);
|
||||
oinfo->dqi_gi.dqi_ops = &ocfs2_global_ops;
|
||||
oinfo->dqi_gqi_bh = NULL;
|
||||
oinfo->dqi_gqi_count = 0;
|
||||
oinfo->dqi_gqinode = gqinode;
|
||||
|
||||
status = ocfs2_lock_global_qf(oinfo, 0);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
status = ocfs2_extent_map_get_blocks(gqinode, 0, &oinfo->dqi_giblk,
|
||||
status = ocfs2_extent_map_get_blocks(oinfo->dqi_gqinode, 0, &oinfo->dqi_giblk,
|
||||
&pcount, NULL);
|
||||
if (status < 0)
|
||||
goto out_unlock;
|
||||
|
|
|
@ -702,8 +702,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
|
|||
info->dqi_priv = oinfo;
|
||||
oinfo->dqi_type = type;
|
||||
INIT_LIST_HEAD(&oinfo->dqi_chunk);
|
||||
oinfo->dqi_gqinode = NULL;
|
||||
ocfs2_qinfo_lock_res_init(&oinfo->dqi_gqlock, oinfo);
|
||||
oinfo->dqi_rec = NULL;
|
||||
oinfo->dqi_lqi_bh = NULL;
|
||||
oinfo->dqi_libh = NULL;
|
||||
|
|
Loading…
Reference in New Issue