diff options
author | Jan Kara <jack@suse.cz> | 2020-09-25 12:14:03 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-10-29 10:12:14 +0100 |
commit | fc9db7fbbf6238ef22e684c29894a4d76911943e (patch) | |
tree | 2887c515a2c9b281220bdc99f17c11c6083fdbef /fs | |
parent | 310594d44c3d66c0472054ec4017243c2d4f8339 (diff) | |
download | linux-stable-fc9db7fbbf6238ef22e684c29894a4d76911943e.tar.gz linux-stable-fc9db7fbbf6238ef22e684c29894a4d76911943e.tar.bz2 linux-stable-fc9db7fbbf6238ef22e684c29894a4d76911943e.zip |
udf: Avoid accessing uninitialized data on failed inode read
[ Upstream commit 044e2e26f214e5ab26af85faffd8d1e4ec066931 ]
When we fail to read inode, some data accessed in udf_evict_inode() may
be uninitialized. Move the accesses to !is_bad_inode() branch.
Reported-by: syzbot+91f02b28f9bb5f5f1341@syzkaller.appspotmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/udf/inode.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index adaba8e8b326..566118417e56 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -139,21 +139,24 @@ void udf_evict_inode(struct inode *inode) struct udf_inode_info *iinfo = UDF_I(inode); int want_delete = 0; - if (!inode->i_nlink && !is_bad_inode(inode)) { - want_delete = 1; - udf_setsize(inode, 0); - udf_update_inode(inode, IS_SYNC(inode)); + if (!is_bad_inode(inode)) { + if (!inode->i_nlink) { + want_delete = 1; + udf_setsize(inode, 0); + udf_update_inode(inode, IS_SYNC(inode)); + } + if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && + inode->i_size != iinfo->i_lenExtents) { + udf_warn(inode->i_sb, + "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n", + inode->i_ino, inode->i_mode, + (unsigned long long)inode->i_size, + (unsigned long long)iinfo->i_lenExtents); + } } truncate_inode_pages_final(&inode->i_data); invalidate_inode_buffers(inode); clear_inode(inode); - if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && - inode->i_size != iinfo->i_lenExtents) { - udf_warn(inode->i_sb, "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n", - inode->i_ino, inode->i_mode, - (unsigned long long)inode->i_size, - (unsigned long long)iinfo->i_lenExtents); - } kfree(iinfo->i_ext.i_data); iinfo->i_ext.i_data = NULL; udf_clear_extent_cache(inode); |