Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a867bbb2 authored by OGAWA Hirofumi's avatar OGAWA Hirofumi Committed by Greg Kroah-Hartman
Browse files

fat: fix uninit-memory access for partial initialized inode



commit bc87302a093f0eab45cd4e250c2021299f712ec6 upstream.

When get an error in the middle of reading an inode, some fields in the
inode might be still not initialized.  And then the evict_inode path may
access those fields via iput().

To fix, this makes sure that inode fields are initialized.

Reported-by: default avatar <syzbot+9d82b8de2992579da5d0@syzkaller.appspotmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: <stable@vger.kernel.org>
Link: http://lkml.kernel.org/r/871rqnreqx.fsf@mail.parknet.co.jp


Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c5451843
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -743,6 +743,13 @@ static struct inode *fat_alloc_inode(struct super_block *sb)
		return NULL;

	init_rwsem(&ei->truncate_lock);
	/* Zeroing to allow iput() even if partial initialized inode. */
	ei->mmu_private = 0;
	ei->i_start = 0;
	ei->i_logstart = 0;
	ei->i_attrs = 0;
	ei->i_pos = 0;

	return &ei->vfs_inode;
}

@@ -1373,16 +1380,6 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
	return 0;
}

static void fat_dummy_inode_init(struct inode *inode)
{
	/* Initialize this dummy inode to work as no-op. */
	MSDOS_I(inode)->mmu_private = 0;
	MSDOS_I(inode)->i_start = 0;
	MSDOS_I(inode)->i_logstart = 0;
	MSDOS_I(inode)->i_attrs = 0;
	MSDOS_I(inode)->i_pos = 0;
}

static int fat_read_root(struct inode *inode)
{
	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
@@ -1827,13 +1824,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
	fat_inode = new_inode(sb);
	if (!fat_inode)
		goto out_fail;
	fat_dummy_inode_init(fat_inode);
	sbi->fat_inode = fat_inode;

	fsinfo_inode = new_inode(sb);
	if (!fsinfo_inode)
		goto out_fail;
	fat_dummy_inode_init(fsinfo_inode);
	fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
	sbi->fsinfo_inode = fsinfo_inode;
	insert_inode_hash(fsinfo_inode);