Skip to content

Commit

Permalink
fat: fix uninit-memory access for partial initialized inode
Browse files Browse the repository at this point in the history
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: [email protected]
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: OGAWA Hirofumi <[email protected]>
Cc: <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
OGAWAHirofumi authored and torvalds committed Mar 6, 2020
1 parent c3e5ea6 commit bc87302
Showing 1 changed file with 7 additions and 12 deletions.
19 changes: 7 additions & 12 deletions fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,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;
}

Expand Down Expand Up @@ -1374,16 +1381,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);
Expand Down Expand Up @@ -1844,13 +1841,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);
Expand Down

0 comments on commit bc87302

Please sign in to comment.