Message ID | 20161207003222.GI16807@birch.djwong.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Darrick, [auto build test WARNING on linus/master] [also build test WARNING on v4.9-rc8 next-20161206] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Darrick-J-Wong/vfs-reject-inodes-with-negative-size-to-prevent-kernel-hang/20161207-110513 config: i386-randconfig-s1-201649 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 Note: it may well be a FALSE warning. FWIW you are at least aware of it now. http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings All warnings (new ones prefixed by >>): Cyclomatic Complexity 1 fs/dcache.c:__d_rehash Cyclomatic Complexity 2 fs/dcache.c:prepend Cyclomatic Complexity 3 fs/dcache.c:path_with_deleted Cyclomatic Complexity 7 fs/dcache.c:__dentry_path Cyclomatic Complexity 1 fs/dcache.c:prepend_unreachable Cyclomatic Complexity 4 fs/dcache.c:d_shrink_del Cyclomatic Complexity 4 fs/dcache.c:d_shrink_add Cyclomatic Complexity 2 fs/dcache.c:__d_instantiate Cyclomatic Complexity 7 fs/dcache.c:d_lru_add Cyclomatic Complexity 2 fs/dcache.c:dentry_lru_add Cyclomatic Complexity 7 fs/dcache.c:d_lru_del Cyclomatic Complexity 7 fs/dcache.c:select_collect Cyclomatic Complexity 2 fs/dcache.c:detach_and_collect Cyclomatic Complexity 6 fs/dcache.c:dentry_unlink_inode Cyclomatic Complexity 1 fs/dcache.c:__d_free_external Cyclomatic Complexity 1 fs/dcache.c:__d_free Cyclomatic Complexity 5 fs/dcache.c:dentry_free Cyclomatic Complexity 4 fs/dcache.c:d_lru_isolate Cyclomatic Complexity 4 fs/dcache.c:d_lru_shrink_move Cyclomatic Complexity 4 fs/dcache.c:dentry_lru_isolate Cyclomatic Complexity 2 fs/dcache.c:dentry_lru_isolate_shrink Cyclomatic Complexity 16 fs/dcache.c:d_walk Cyclomatic Complexity 6 fs/dcache.c:umount_check Cyclomatic Complexity 3 fs/dcache.c:d_wait_lookup Cyclomatic Complexity 6 fs/dcache.c:swap_names Cyclomatic Complexity 6 fs/dcache.c:copy_name Cyclomatic Complexity 2 fs/dcache.c:set_dhash_entries Cyclomatic Complexity 1 fs/dcache.c:vfs_caches_init_early Cyclomatic Complexity 1 fs/dcache.c:vfs_caches_init Cyclomatic Complexity 1 fs/dcache.c:proc_nr_dentry Cyclomatic Complexity 3 fs/dcache.c:__d_drop Cyclomatic Complexity 11 fs/dcache.c:__dentry_kill Cyclomatic Complexity 6 fs/dcache.c:dentry_kill Cyclomatic Complexity 16 fs/dcache.c:shrink_dentry_list Cyclomatic Complexity 3 fs/dcache.c:check_and_drop Cyclomatic Complexity 1 fs/dcache.c:d_drop Cyclomatic Complexity 10 fs/dcache.c:dput Cyclomatic Complexity 4 fs/dcache.c:dget_parent Cyclomatic Complexity 2 fs/dcache.c:d_find_alias Cyclomatic Complexity 7 fs/dcache.c:d_prune_aliases Cyclomatic Complexity 1 fs/dcache.c:prune_dcache_sb Cyclomatic Complexity 6 fs/dcache.c:shrink_dcache_sb Cyclomatic Complexity 1 fs/dcache.c:have_submounts Cyclomatic Complexity 4 fs/dcache.c:d_set_mounted Cyclomatic Complexity 2 fs/dcache.c:shrink_dcache_parent Cyclomatic Complexity 1 fs/dcache.c:do_one_tree Cyclomatic Complexity 3 fs/dcache.c:shrink_dcache_for_umount Cyclomatic Complexity 7 fs/dcache.c:d_invalidate Cyclomatic Complexity 15 fs/dcache.c:d_set_d_op Cyclomatic Complexity 9 fs/dcache.c:__d_alloc Cyclomatic Complexity 2 fs/dcache.c:d_alloc Cyclomatic Complexity 1 fs/dcache.c:d_alloc_name Cyclomatic Complexity 2 fs/dcache.c:d_alloc_cursor Cyclomatic Complexity 1 fs/dcache.c:d_alloc_pseudo Cyclomatic Complexity 1 fs/dcache.c:d_set_fallthru Cyclomatic Complexity 2 fs/dcache.c:d_instantiate Cyclomatic Complexity 3 fs/dcache.c:d_instantiate_no_diralias Cyclomatic Complexity 3 fs/dcache.c:d_make_root Cyclomatic Complexity 1 fs/dcache.c:d_find_any_alias Cyclomatic Complexity 7 fs/dcache.c:__d_obtain_alias Cyclomatic Complexity 1 fs/dcache.c:d_obtain_alias Cyclomatic Complexity 1 fs/dcache.c:d_obtain_root Cyclomatic Complexity 11 fs/dcache.c:__d_lookup_rcu Cyclomatic Complexity 7 fs/dcache.c:__d_lookup Cyclomatic Complexity 3 fs/dcache.c:d_lookup Cyclomatic Complexity 3 fs/dcache.c:d_hash_and_lookup Cyclomatic Complexity 4 fs/dcache.c:d_delete Cyclomatic Complexity 1 fs/dcache.c:d_rehash Cyclomatic Complexity 18 fs/dcache.c:d_alloc_parallel Cyclomatic Complexity 1 fs/dcache.c:__d_lookup_done Cyclomatic Complexity 2 fs/dcache.c:d_add Cyclomatic Complexity 8 fs/dcache.c:d_exact_alias Cyclomatic Complexity 1 fs/dcache.c:dentry_update_name_case Cyclomatic Complexity 3 fs/dcache.c:d_ancestor Cyclomatic Complexity 5 fs/dcache.c:dentry_lock_for_move Cyclomatic Complexity 8 fs/dcache.c:__d_move Cyclomatic Complexity 1 fs/dcache.c:d_move Cyclomatic Complexity 5 fs/dcache.c:d_exchange Cyclomatic Complexity 6 fs/dcache.c:__d_unalias Cyclomatic Complexity 13 fs/dcache.c:d_splice_alias Cyclomatic Complexity 7 fs/dcache.c:d_add_ci Cyclomatic Complexity 3 fs/dcache.c:__d_path Cyclomatic Complexity 3 fs/dcache.c:d_absolute_path Cyclomatic Complexity 6 fs/dcache.c:d_path Cyclomatic Complexity 2 fs/dcache.c:dynamic_dname Cyclomatic Complexity 4 fs/dcache.c:simple_dname Cyclomatic Complexity 1 fs/dcache.c:dentry_path_raw Cyclomatic Complexity 5 fs/dcache.c:dentry_path Cyclomatic Complexity 1 fs/dcache.c:SyS_getcwd Cyclomatic Complexity 4 fs/dcache.c:is_subdir Cyclomatic Complexity 1 fs/dcache.c:d_genocide Cyclomatic Complexity 4 fs/dcache.c:d_tmpfile In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/syscalls.h:70, from fs/dcache.c:17: fs/dcache.c: In function 'd_add': >> include/linux/compiler.h:323:14: warning: 'n' may be used uninitialized in this function [-Wmaybe-uninitialized] { .__val = (__force typeof(x)) (val) }; \ ^ fs/dcache.c:2520:11: note: 'n' was declared here unsigned n; ^ In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/syscalls.h:70, from fs/dcache.c:17: fs/dcache.c: In function 'd_splice_alias': >> include/linux/compiler.h:323:14: warning: 'n' may be used uninitialized in this function [-Wmaybe-uninitialized] { .__val = (__force typeof(x)) (val) }; \ ^ fs/dcache.c:2520:11: note: 'n' was declared here unsigned n; ^ vim +/n +323 include/linux/compiler.h d976441f Andrey Ryabinin 2015-10-19 307 __read_once_size(&(x), __u.__c, sizeof(x)); \ d976441f Andrey Ryabinin 2015-10-19 308 else \ d976441f Andrey Ryabinin 2015-10-19 309 __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \ d976441f Andrey Ryabinin 2015-10-19 310 __u.__val; \ d976441f Andrey Ryabinin 2015-10-19 311 }) d976441f Andrey Ryabinin 2015-10-19 312 #define READ_ONCE(x) __READ_ONCE(x, 1) d976441f Andrey Ryabinin 2015-10-19 313 d976441f Andrey Ryabinin 2015-10-19 314 /* d976441f Andrey Ryabinin 2015-10-19 315 * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need d976441f Andrey Ryabinin 2015-10-19 316 * to hide memory access from KASAN. d976441f Andrey Ryabinin 2015-10-19 317 */ d976441f Andrey Ryabinin 2015-10-19 318 #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0) 230fa253 Christian Borntraeger 2014-11-25 319 43239cbe Christian Borntraeger 2015-01-13 320 #define WRITE_ONCE(x, val) \ ba33034f Christian Borntraeger 2015-08-04 321 ({ \ ba33034f Christian Borntraeger 2015-08-04 322 union { typeof(x) __val; char __c[1]; } __u = \ ba33034f Christian Borntraeger 2015-08-04 @323 { .__val = (__force typeof(x)) (val) }; \ ba33034f Christian Borntraeger 2015-08-04 324 __write_once_size(&(x), __u.__c, sizeof(x)); \ ba33034f Christian Borntraeger 2015-08-04 325 __u.__val; \ ba33034f Christian Borntraeger 2015-08-04 326 }) 230fa253 Christian Borntraeger 2014-11-25 327 ^1da177e Linus Torvalds 2005-04-16 328 #endif /* __KERNEL__ */ ^1da177e Linus Torvalds 2005-04-16 329 ^1da177e Linus Torvalds 2005-04-16 330 #endif /* __ASSEMBLY__ */ ^1da177e Linus Torvalds 2005-04-16 331 :::::: The code at line 323 was first introduced by commit :::::: ba33034fffc1189d95301bd865f1c799256e72a2 locking, compiler.h: Cast away attributes in the WRITE_ONCE() magic :::::: TO: Christian Borntraeger <borntraeger@de.ibm.com> :::::: CC: Ingo Molnar <mingo@kernel.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Wed, Dec 07, 2016 at 11:54:52AM +0800, kbuild test robot wrote: > Hi Darrick, > > [auto build test WARNING on linus/master] > [also build test WARNING on v4.9-rc8 next-20161206] > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] > > url: https://github.com/0day-ci/linux/commits/Darrick-J-Wong/vfs-reject-inodes-with-negative-size-to-prevent-kernel-hang/20161207-110513 > config: i386-randconfig-s1-201649 (attached as .config) > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > Note: it may well be a FALSE warning. FWIW you are at least aware of it now. > http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings > > All warnings (new ones prefixed by >>): > > Cyclomatic Complexity 1 fs/dcache.c:__d_rehash > Cyclomatic Complexity 2 fs/dcache.c:prepend > Cyclomatic Complexity 3 fs/dcache.c:path_with_deleted > Cyclomatic Complexity 7 fs/dcache.c:__dentry_path > Cyclomatic Complexity 1 fs/dcache.c:prepend_unreachable > Cyclomatic Complexity 4 fs/dcache.c:d_shrink_del > Cyclomatic Complexity 4 fs/dcache.c:d_shrink_add > Cyclomatic Complexity 2 fs/dcache.c:__d_instantiate > Cyclomatic Complexity 7 fs/dcache.c:d_lru_add > Cyclomatic Complexity 2 fs/dcache.c:dentry_lru_add > Cyclomatic Complexity 7 fs/dcache.c:d_lru_del > Cyclomatic Complexity 7 fs/dcache.c:select_collect > Cyclomatic Complexity 2 fs/dcache.c:detach_and_collect > Cyclomatic Complexity 6 fs/dcache.c:dentry_unlink_inode > Cyclomatic Complexity 1 fs/dcache.c:__d_free_external > Cyclomatic Complexity 1 fs/dcache.c:__d_free > Cyclomatic Complexity 5 fs/dcache.c:dentry_free > Cyclomatic Complexity 4 fs/dcache.c:d_lru_isolate > Cyclomatic Complexity 4 fs/dcache.c:d_lru_shrink_move > Cyclomatic Complexity 4 fs/dcache.c:dentry_lru_isolate > Cyclomatic Complexity 2 fs/dcache.c:dentry_lru_isolate_shrink > Cyclomatic Complexity 16 fs/dcache.c:d_walk > Cyclomatic Complexity 6 fs/dcache.c:umount_check > Cyclomatic Complexity 3 fs/dcache.c:d_wait_lookup > Cyclomatic Complexity 6 fs/dcache.c:swap_names > Cyclomatic Complexity 6 fs/dcache.c:copy_name > Cyclomatic Complexity 2 fs/dcache.c:set_dhash_entries > Cyclomatic Complexity 1 fs/dcache.c:vfs_caches_init_early > Cyclomatic Complexity 1 fs/dcache.c:vfs_caches_init > Cyclomatic Complexity 1 fs/dcache.c:proc_nr_dentry > Cyclomatic Complexity 3 fs/dcache.c:__d_drop > Cyclomatic Complexity 11 fs/dcache.c:__dentry_kill > Cyclomatic Complexity 6 fs/dcache.c:dentry_kill > Cyclomatic Complexity 16 fs/dcache.c:shrink_dentry_list > Cyclomatic Complexity 3 fs/dcache.c:check_and_drop > Cyclomatic Complexity 1 fs/dcache.c:d_drop > Cyclomatic Complexity 10 fs/dcache.c:dput > Cyclomatic Complexity 4 fs/dcache.c:dget_parent > Cyclomatic Complexity 2 fs/dcache.c:d_find_alias > Cyclomatic Complexity 7 fs/dcache.c:d_prune_aliases > Cyclomatic Complexity 1 fs/dcache.c:prune_dcache_sb > Cyclomatic Complexity 6 fs/dcache.c:shrink_dcache_sb > Cyclomatic Complexity 1 fs/dcache.c:have_submounts > Cyclomatic Complexity 4 fs/dcache.c:d_set_mounted > Cyclomatic Complexity 2 fs/dcache.c:shrink_dcache_parent > Cyclomatic Complexity 1 fs/dcache.c:do_one_tree > Cyclomatic Complexity 3 fs/dcache.c:shrink_dcache_for_umount > Cyclomatic Complexity 7 fs/dcache.c:d_invalidate > Cyclomatic Complexity 15 fs/dcache.c:d_set_d_op > Cyclomatic Complexity 9 fs/dcache.c:__d_alloc > Cyclomatic Complexity 2 fs/dcache.c:d_alloc > Cyclomatic Complexity 1 fs/dcache.c:d_alloc_name > Cyclomatic Complexity 2 fs/dcache.c:d_alloc_cursor > Cyclomatic Complexity 1 fs/dcache.c:d_alloc_pseudo > Cyclomatic Complexity 1 fs/dcache.c:d_set_fallthru > Cyclomatic Complexity 2 fs/dcache.c:d_instantiate > Cyclomatic Complexity 3 fs/dcache.c:d_instantiate_no_diralias > Cyclomatic Complexity 3 fs/dcache.c:d_make_root > Cyclomatic Complexity 1 fs/dcache.c:d_find_any_alias > Cyclomatic Complexity 7 fs/dcache.c:__d_obtain_alias > Cyclomatic Complexity 1 fs/dcache.c:d_obtain_alias > Cyclomatic Complexity 1 fs/dcache.c:d_obtain_root > Cyclomatic Complexity 11 fs/dcache.c:__d_lookup_rcu > Cyclomatic Complexity 7 fs/dcache.c:__d_lookup > Cyclomatic Complexity 3 fs/dcache.c:d_lookup > Cyclomatic Complexity 3 fs/dcache.c:d_hash_and_lookup > Cyclomatic Complexity 4 fs/dcache.c:d_delete > Cyclomatic Complexity 1 fs/dcache.c:d_rehash > Cyclomatic Complexity 18 fs/dcache.c:d_alloc_parallel > Cyclomatic Complexity 1 fs/dcache.c:__d_lookup_done > Cyclomatic Complexity 2 fs/dcache.c:d_add > Cyclomatic Complexity 8 fs/dcache.c:d_exact_alias > Cyclomatic Complexity 1 fs/dcache.c:dentry_update_name_case > Cyclomatic Complexity 3 fs/dcache.c:d_ancestor > Cyclomatic Complexity 5 fs/dcache.c:dentry_lock_for_move > Cyclomatic Complexity 8 fs/dcache.c:__d_move > Cyclomatic Complexity 1 fs/dcache.c:d_move > Cyclomatic Complexity 5 fs/dcache.c:d_exchange > Cyclomatic Complexity 6 fs/dcache.c:__d_unalias > Cyclomatic Complexity 13 fs/dcache.c:d_splice_alias > Cyclomatic Complexity 7 fs/dcache.c:d_add_ci > Cyclomatic Complexity 3 fs/dcache.c:__d_path > Cyclomatic Complexity 3 fs/dcache.c:d_absolute_path > Cyclomatic Complexity 6 fs/dcache.c:d_path > Cyclomatic Complexity 2 fs/dcache.c:dynamic_dname > Cyclomatic Complexity 4 fs/dcache.c:simple_dname > Cyclomatic Complexity 1 fs/dcache.c:dentry_path_raw > Cyclomatic Complexity 5 fs/dcache.c:dentry_path > Cyclomatic Complexity 1 fs/dcache.c:SyS_getcwd > Cyclomatic Complexity 4 fs/dcache.c:is_subdir > Cyclomatic Complexity 1 fs/dcache.c:d_genocide > Cyclomatic Complexity 4 fs/dcache.c:d_tmpfile > In file included from include/uapi/linux/stddef.h:1:0, > from include/linux/stddef.h:4, > from include/uapi/linux/posix_types.h:4, > from include/uapi/linux/types.h:13, > from include/linux/types.h:5, > from include/linux/syscalls.h:70, > from fs/dcache.c:17: > fs/dcache.c: In function 'd_add': > >> include/linux/compiler.h:323:14: warning: 'n' may be used uninitialized in this function [-Wmaybe-uninitialized] Uh... I don't touch _n_ in this patch, and AFAICT I don't alter any of the code paths that access _n_. <shrugs vaguely at the robotic reply address> --D > { .__val = (__force typeof(x)) (val) }; \ > ^ > fs/dcache.c:2520:11: note: 'n' was declared here > unsigned n; > ^ > In file included from include/uapi/linux/stddef.h:1:0, > from include/linux/stddef.h:4, > from include/uapi/linux/posix_types.h:4, > from include/uapi/linux/types.h:13, > from include/linux/types.h:5, > from include/linux/syscalls.h:70, > from fs/dcache.c:17: > fs/dcache.c: In function 'd_splice_alias': > >> include/linux/compiler.h:323:14: warning: 'n' may be used uninitialized in this function [-Wmaybe-uninitialized] > { .__val = (__force typeof(x)) (val) }; \ > ^ > fs/dcache.c:2520:11: note: 'n' was declared here > unsigned n; > ^ > > vim +/n +323 include/linux/compiler.h > > d976441f Andrey Ryabinin 2015-10-19 307 __read_once_size(&(x), __u.__c, sizeof(x)); \ > d976441f Andrey Ryabinin 2015-10-19 308 else \ > d976441f Andrey Ryabinin 2015-10-19 309 __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \ > d976441f Andrey Ryabinin 2015-10-19 310 __u.__val; \ > d976441f Andrey Ryabinin 2015-10-19 311 }) > d976441f Andrey Ryabinin 2015-10-19 312 #define READ_ONCE(x) __READ_ONCE(x, 1) > d976441f Andrey Ryabinin 2015-10-19 313 > d976441f Andrey Ryabinin 2015-10-19 314 /* > d976441f Andrey Ryabinin 2015-10-19 315 * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need > d976441f Andrey Ryabinin 2015-10-19 316 * to hide memory access from KASAN. > d976441f Andrey Ryabinin 2015-10-19 317 */ > d976441f Andrey Ryabinin 2015-10-19 318 #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0) > 230fa253 Christian Borntraeger 2014-11-25 319 > 43239cbe Christian Borntraeger 2015-01-13 320 #define WRITE_ONCE(x, val) \ > ba33034f Christian Borntraeger 2015-08-04 321 ({ \ > ba33034f Christian Borntraeger 2015-08-04 322 union { typeof(x) __val; char __c[1]; } __u = \ > ba33034f Christian Borntraeger 2015-08-04 @323 { .__val = (__force typeof(x)) (val) }; \ > ba33034f Christian Borntraeger 2015-08-04 324 __write_once_size(&(x), __u.__c, sizeof(x)); \ > ba33034f Christian Borntraeger 2015-08-04 325 __u.__val; \ > ba33034f Christian Borntraeger 2015-08-04 326 }) > 230fa253 Christian Borntraeger 2014-11-25 327 > ^1da177e Linus Torvalds 2005-04-16 328 #endif /* __KERNEL__ */ > ^1da177e Linus Torvalds 2005-04-16 329 > ^1da177e Linus Torvalds 2005-04-16 330 #endif /* __ASSEMBLY__ */ > ^1da177e Linus Torvalds 2005-04-16 331 > > :::::: The code at line 323 was first introduced by commit > :::::: ba33034fffc1189d95301bd865f1c799256e72a2 locking, compiler.h: Cast away attributes in the WRITE_ONCE() magic > > :::::: TO: Christian Borntraeger <borntraeger@de.ibm.com> > :::::: CC: Ingo Molnar <mingo@kernel.org> > > --- > 0-DAY kernel test infrastructure Open Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Dec 06, 2016 at 04:32:22PM -0800, Darrick J. Wong wrote: > Due to insufficient input validation, various filesystem drivers can > load an inode with a negative size from a maliciously crafted fs image. > If this happens, a subsequent write-append operation can cause integer > overflows in the writeback code, causing the kernel to lock up. > > Therefore, if we catch anyone trying to link a dentry to a garbage > inode, reject the whole attempt. Yecchh... This is completely wrong place for such checks. Sorry, NAK. The set of spots chosen for those tests is random *and* it's not even sufficient (consider e.g. d_obtain_alias()). The things go wrong when such inode is set up, not when a dentry is attached to it. -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/dcache.c b/fs/dcache.c index 5c7cc95..6a253a4 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2524,6 +2524,17 @@ static inline void __d_add(struct dentry *dentry, struct inode *inode) n = start_dir_add(dir); __d_lookup_done(dentry); } + + /* + * Someone fed us an inode with negative size?! This can cause + * integer overflows in other parts of the VFS, so reject this. + */ + if (inode && i_size_read(inode) < 0) { + WARN_ON_ONCE(1); + iput(inode); + inode = NULL; + } + if (inode) { unsigned add_flags = d_flags_for_inode(inode); hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); @@ -2946,6 +2957,16 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) if (!inode) goto out; + /* + * Someone fed us an inode with negative size?! This can cause + * integer overflows in other parts of the VFS, so reject this. + */ + if (i_size_read(inode) < 0) { + WARN_ON_ONCE(1); + iput(inode); + return ERR_PTR(-EUCLEAN); + } + security_d_instantiate(dentry, inode); spin_lock(&inode->i_lock); if (S_ISDIR(inode->i_mode)) {
Due to insufficient input validation, various filesystem drivers can load an inode with a negative size from a maliciously crafted fs image. If this happens, a subsequent write-append operation can cause integer overflows in the writeback code, causing the kernel to lock up. Therefore, if we catch anyone trying to link a dentry to a garbage inode, reject the whole attempt. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- The regression tests for this bug are {ext4,xfs}/40[01] in the patch "xfs/ext4: check negative inode size" that I just sent to fstests@vger. I realize it's /very/ late in the 4.9 cycle, but this seemed like the most general way to fix this problem. Perhaps a better fix is to strengthen the _iget verification in every filesystem, which I'm working on for 4.10. But we should at the very least bonk suspicious looking activity. :) --- fs/dcache.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html