Skip to content

Commit de19433

Browse files
josephhztorvalds
authored andcommitted
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 commit 6c85c2c, 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: 6c85c2c ("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>
1 parent e6b0a7b commit de19433

2 files changed

Lines changed: 12 additions & 13 deletions

File tree

fs/ocfs2/quota_global.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@ void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex)
337337
/* Read information header from global quota file */
338338
int ocfs2_global_read_info(struct super_block *sb, int type)
339339
{
340-
struct inode *gqinode = NULL;
341340
unsigned int ino[OCFS2_MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
342341
GROUP_QUOTA_SYSTEM_INODE };
343342
struct ocfs2_global_disk_dqinfo dinfo;
@@ -346,29 +345,31 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
346345
u64 pcount;
347346
int status;
348347

348+
oinfo->dqi_gi.dqi_sb = sb;
349+
oinfo->dqi_gi.dqi_type = type;
350+
ocfs2_qinfo_lock_res_init(&oinfo->dqi_gqlock, oinfo);
351+
oinfo->dqi_gi.dqi_entry_size = sizeof(struct ocfs2_global_disk_dqblk);
352+
oinfo->dqi_gi.dqi_ops = &ocfs2_global_ops;
353+
oinfo->dqi_gqi_bh = NULL;
354+
oinfo->dqi_gqi_count = 0;
355+
349356
/* Read global header */
350-
gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
357+
oinfo->dqi_gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
351358
OCFS2_INVALID_SLOT);
352-
if (!gqinode) {
359+
if (!oinfo->dqi_gqinode) {
353360
mlog(ML_ERROR, "failed to get global quota inode (type=%d)\n",
354361
type);
355362
status = -EINVAL;
356363
goto out_err;
357364
}
358-
oinfo->dqi_gi.dqi_sb = sb;
359-
oinfo->dqi_gi.dqi_type = type;
360-
oinfo->dqi_gi.dqi_entry_size = sizeof(struct ocfs2_global_disk_dqblk);
361-
oinfo->dqi_gi.dqi_ops = &ocfs2_global_ops;
362-
oinfo->dqi_gqi_bh = NULL;
363-
oinfo->dqi_gqi_count = 0;
364-
oinfo->dqi_gqinode = gqinode;
365+
365366
status = ocfs2_lock_global_qf(oinfo, 0);
366367
if (status < 0) {
367368
mlog_errno(status);
368369
goto out_err;
369370
}
370371

371-
status = ocfs2_extent_map_get_blocks(gqinode, 0, &oinfo->dqi_giblk,
372+
status = ocfs2_extent_map_get_blocks(oinfo->dqi_gqinode, 0, &oinfo->dqi_giblk,
372373
&pcount, NULL);
373374
if (status < 0)
374375
goto out_unlock;

fs/ocfs2/quota_local.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
702702
info->dqi_priv = oinfo;
703703
oinfo->dqi_type = type;
704704
INIT_LIST_HEAD(&oinfo->dqi_chunk);
705-
oinfo->dqi_gqinode = NULL;
706-
ocfs2_qinfo_lock_res_init(&oinfo->dqi_gqlock, oinfo);
707705
oinfo->dqi_rec = NULL;
708706
oinfo->dqi_lqi_bh = NULL;
709707
oinfo->dqi_libh = NULL;

0 commit comments

Comments
 (0)