lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <5a3a9cdc-33c3-4196-b8f7-bfec485eae5b@linux.dev>
Date:   Mon, 23 May 2022 16:51:50 +0800
From:   Jackie Liu <liu.yun@...ux.dev>
To:     darrick.wong@...cle.com
Cc:     linux-xfs@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [BUG report] security_inode_alloc return -ENOMEM let xfs shutdown

Hello Maintainer and developer.

    Syzkaller report an filesystem shutdown for me, It's very easy to
trigger and also exists on the latest kernel version 5.18-rc7.

dmesg shows:

[  285.725893] FAULT_INJECTION: forcing a failure.
                name failslab, interval 1, probability 0, space 0, times 0
[  285.729625] CPU: 7 PID: 18034 Comm: syz-executor Not tainted 
4.19.90-43+ #7
[  285.731420] Source Version: b62cabdd86181d386998660ebf34ca653addd6c9
[  285.733051] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 
02/06/2015
[  285.734796] Call trace:
[  285.735614]  dump_backtrace+0x0/0x3e0
[  285.736609]  show_stack+0x2c/0x38
[  285.737525]  dump_stack+0x164/0x1fc
[  285.738489]  should_fail+0x5c0/0x688
[  285.739555]  __should_failslab+0x118/0x180
[  285.740725]  should_failslab+0x2c/0x78
[  285.741808]  kmem_cache_alloc_trace+0x270/0x410
[  285.743120]  security_inode_alloc+0x100/0x1a8
[  285.744356]  inode_init_always+0x48c/0xa28
[  285.745524]  xfs_iget_cache_hit+0x9c0/0x2f28
[  285.746739]  xfs_iget+0x33c/0x9e0
[  285.747708]  xfs_ialloc+0x218/0x11c0
[  285.748752]  xfs_dir_ialloc+0xe8/0x480
[  285.749832]  xfs_create+0x5bc/0x1220
[  285.750871]  xfs_generic_create+0x42c/0x568
[  285.752053]  xfs_vn_mknod+0x48/0x58
[  285.753067]  xfs_vn_create+0x40/0x50
[  285.754106]  lookup_open+0x960/0x1580
[  285.755176]  do_last+0xd44/0x2180
[  285.756149]  path_openat+0x1a0/0x6d0
[  285.757187]  do_filp_open+0x14c/0x208
[  285.758245]  do_sys_open+0x340/0x470
[  285.759289]  __arm64_sys_openat+0x98/0xd8
[  285.760438]  el0_svc_common+0x230/0x3f0
[  285.761541]  el0_svc_handler+0x144/0x1a8
[  285.762674]  el0_svc+0x8/0x1b0
[  285.763737] security_inode_alloc:796
[  285.764733] inode_init_always:202
[  285.765669] xfs_create:1213
[  285.766485] XFS (dm-0): Internal error xfs_trans_cancel at line 1046 
of file fs/xfs/xfs_trans.c.  Caller xfs_create+0x700/0x1220
[  285.769503] CPU: 7 PID: 18034 Comm: syz-executor Not tainted 
4.19.90-43+ #7
[  285.771275] Source Version: b62cabdd86181d386998660ebf34ca653addd6c9
[  285.772892] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 
02/06/2015
[  285.774625] Call trace:
[  285.775335]  dump_backtrace+0x0/0x3e0
[  285.776324]  show_stack+0x2c/0x38
[  285.777236]  dump_stack+0x164/0x1fc
[  285.778188]  xfs_error_report+0xdc/0xe0
[  285.779292]  xfs_trans_cancel+0x490/0x878
[  285.780439]  xfs_create+0x700/0x1220
[  285.781477]  xfs_generic_create+0x42c/0x568
[  285.782673]  xfs_vn_mknod+0x48/0x58
[  285.783687]  xfs_vn_create+0x40/0x50
[  285.784724]  lookup_open+0x960/0x1580
[  285.785782]  do_last+0xd44/0x2180
[  285.786760]  path_openat+0x1a0/0x6d0
[  285.787791]  do_filp_open+0x14c/0x208
[  285.788844]  do_sys_open+0x340/0x470
[  285.789880]  __arm64_sys_openat+0x98/0xd8
[  285.791039]  el0_svc_common+0x230/0x3f0
[  285.792139]  el0_svc_handler+0x144/0x1a8
[  285.793260]  el0_svc+0x8/0x1b0
[  285.794283] XFS (dm-0): xfs_do_force_shutdown(0x8) called from line 
1047 of file fs/xfs/xfs_trans.c.  Return address = 00000000a4a366b9
[  285.816187] XFS (dm-0): Corruption of in-memory data detected. 
Shutting down filesystem
[  285.818476] XFS (dm-0): Please umount the filesystem and rectify the 
problem(s)

I found that it is not allowed to fail when alloc xfs_inode in
xfs_inode_alloc , but allow inode_init_always to report -ENOMEM?

inode_init_always is not failed by security_inode_alloc.

I have test the patch:

diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index ceee27b70384..609ad96e29e9 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -43,12 +43,14 @@ xfs_inode_alloc(
          * code up to do this anyway.
          */
         ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
-       if (!ip)
-               return NULL;
-       if (inode_init_always(mp->m_super, VFS_I(ip))) {
-               kmem_zone_free(xfs_inode_zone, ip);
+       if (!ip) {
+               pr_err("%s:%d\n", __func__, __LINE__);
                 return NULL;
         }
+       while (inode_init_always(mp->m_super, VFS_I(ip)) != 0) {
+               pr_err("%s:%d\n", __func__, __LINE__);
+               pr_err("111\n");
+       }

         /* VFS doesn't initialise i_mode! */
         VFS_I(ip)->i_mode = 0;
@@ -280,7 +282,7 @@ xfs_reinit_inode(
         struct xfs_mount        *mp,
         struct inode            *inode)
  {
-       int             error;
+       int             error = 0;
         uint32_t        nlink = inode->i_nlink;
         uint32_t        generation = inode->i_generation;
         uint64_t        version = inode_peek_iversion(inode);
@@ -289,7 +291,7 @@ xfs_reinit_inode(
         kuid_t          uid = inode->i_uid;
         kgid_t          gid = inode->i_gid;

-       error = inode_init_always(mp->m_super, inode);
+       while (inode_init_always(mp->m_super, inode) != 0);

         set_nlink(inode, nlink);
         inode->i_generation = generation;

syzkaller works fine.

Does anyone help me, Any suggestion is welcome.

--
BR, Jackie Liu

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ