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-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aWb+7/g7Nz1zfFSp@ly-workstation>
Date: Wed, 14 Jan 2026 10:26:55 +0800
From: "Lai, Yi" <yi1.lai@...ux.intel.com>
To: Mateusz Guzik <mjguzik@...il.com>
Cc: brauner@...nel.org, viro@...iv.linux.org.uk, jack@...e.cz,
	linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org
Subject: Re: [PATCH] fs: make insert_inode_locked() wait for inode destruction

On Sun, Jan 11, 2026 at 09:38:42AM +0100, Mateusz Guzik wrote:
> This is the only routine which instead skipped instead of waiting.
> 
> The current behavior is arguably a bug as it results in a corner case
> where the inode hash can have *two* matching inodes, one of which is on
> its way out.
> 
> Ironing out this difference is an incremental step towards sanitizing
> the API.
> 
> Signed-off-by: Mateusz Guzik <mjguzik@...il.com>
> ---
>  fs/inode.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index f8904f813372..3b838f07cb40 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -1832,16 +1832,13 @@ int insert_inode_locked(struct inode *inode)
>  	while (1) {
>  		struct inode *old = NULL;
>  		spin_lock(&inode_hash_lock);
> +repeat:
>  		hlist_for_each_entry(old, head, i_hash) {
>  			if (old->i_ino != ino)
>  				continue;
>  			if (old->i_sb != sb)
>  				continue;
>  			spin_lock(&old->i_lock);
> -			if (inode_state_read(old) & (I_FREEING | I_WILL_FREE)) {
> -				spin_unlock(&old->i_lock);
> -				continue;
> -			}
>  			break;
>  		}
>  		if (likely(!old)) {
> @@ -1852,6 +1849,11 @@ int insert_inode_locked(struct inode *inode)
>  			spin_unlock(&inode_hash_lock);
>  			return 0;
>  		}
> +		if (inode_state_read(old) & (I_FREEING | I_WILL_FREE)) {
> +			__wait_on_freeing_inode(old, true);
> +			old = NULL;
> +			goto repeat;
> +		}
>  		if (unlikely(inode_state_read(old) & I_CREATING)) {
>  			spin_unlock(&old->i_lock);
>  			spin_unlock(&inode_hash_lock);
> -- 
> 2.48.1
>

Hi Mateusz Guzik,

Greetings!

I used Syzkaller and found that there is WARNING: bad unlock balance in __wait_on_freeing_inode in linux-next next-20260113.

After bisection and the first bad commit is:
"
757b907b3ead fs: make insert_inode_locked() wait for inode destruction
"

All detailed into can be found at:
https://github.com/laifryiee/syzkaller_logs/tree/main/260113_160659___wait_on_freeing_inode
Syzkaller repro code:
https://github.com/laifryiee/syzkaller_logs/tree/main/260113_160659___wait_on_freeing_inode/repro.c
Syzkaller repro syscall steps:
https://github.com/laifryiee/syzkaller_logs/tree/main/260113_160659___wait_on_freeing_inode/repro.prog
Syzkaller report:
https://github.com/laifryiee/syzkaller_logs/tree/main/260113_160659___wait_on_freeing_inode/repro.report
Kconfig(make olddefconfig):
https://github.com/laifryiee/syzkaller_logs/tree/main/260113_160659___wait_on_freeing_inode/kconfig_origin
Bisect info:
https://github.com/laifryiee/syzkaller_logs/tree/main/260113_160659___wait_on_freeing_inode/bisect_info.log
bzImage:
https://github.com/laifryiee/syzkaller_logs/raw/refs/heads/main/260113_160659___wait_on_freeing_inode/bzImage_0f853ca2a798ead9d24d39cad99b0966815c582a
Issue dmesg:
https://github.com/laifryiee/syzkaller_logs/blob/main/260113_160659___wait_on_freeing_inode/0f853ca2a798ead9d24d39cad99b0966815c582a_dmesg.log

"
[   57.740820] =====================================
[   57.741171] WARNING: bad unlock balance detected!
[   57.741521] 6.19.0-rc5-next-20260113-0f853ca2a798 #1 Not tainted
[   57.741960] -------------------------------------
[   57.742317] repro/663 is trying to release lock (rcu_read_lock) at:
[   57.742831] [<ffffffff821343ea>] __wait_on_freeing_inode+0x13a/0x3b0
[   57.743361] but there are no more locks to release!
[   57.743744]
[   57.743744] other info that might help us debug this:
[   57.744238] 4 locks held by repro/663:
[   57.744531]  #0: ffff888012d42408 (sb_writers#3){.+.+}-{0:0}, at: filename_create+0x122/0x460
[   57.745228]  #1: ffff88802685d9f0 (&type->i_mutex_dir_key#3/1){+.+.}-{4:4}, at: filename_create+0x1e6/0x460
[   57.746024]  #2: ffff888012d54950 (jbd2_handle){++++}-{0:0}, at: start_this_handle+0x1042/0x1550
[   57.746741]  #3: ffffffff87416918 (inode_hash_lock){+.+.}-{3:3}, at: insert_inode_locked+0xf4/0x860
[   57.747472]
[   57.747472] stack backtrace:
[   57.747831] CPU: 1 UID: 0 PID: 663 Comm: repro Not tainted 6.19.0-rc5-next-20260113-0f853ca2a798 #1 PREEMPT(lazy)
[   57.747849] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org4
[   57.747860] Call Trace:
[   57.747873]  <TASK>
[   57.747882]  dump_stack_lvl+0xea/0x150
[   57.747932]  ? __wait_on_freeing_inode+0x13a/0x3b0
[   57.747946]  dump_stack+0x19/0x20
[   57.747965]  print_unlock_imbalance_bug+0x121/0x140
[   57.748003]  ? __wait_on_freeing_inode+0x13a/0x3b0
[   57.748017]  lock_release+0x211/0x2a0
[   57.748031]  __wait_on_freeing_inode+0x13f/0x3b0
[   57.748046]  ? __pfx___wait_on_freeing_inode+0x10/0x10
[   57.748060]  ? do_raw_spin_lock+0x140/0x280
[   57.748081]  ? __pfx_var_wake_function+0x10/0x10
[   57.748097]  ? __this_cpu_preempt_check+0x21/0x30
[   57.748117]  ? lock_is_held_type+0xef/0x150
[   57.748138]  insert_inode_locked+0x26c/0x860
[   57.748155]  __ext4_new_inode+0x1c4a/0x5230
[   57.748192]  ? __pfx___ext4_new_inode+0x10/0x10
[   57.748211]  ? __pfx___dquot_initialize+0x10/0x10
[   57.748238]  ? ext4_lookup+0xe7/0x710
[   57.748254]  ? __this_cpu_preempt_check+0x21/0x30
[   57.748269]  ext4_mkdir+0x360/0xb70
[   57.748285]  ? __pfx_ext4_mkdir+0x10/0x10
[   57.748296]  ? security_inode_permission+0xb8/0x220
[   57.748327]  ? inode_permission+0x39d/0x690
[   57.748341]  ? __sanitizer_cov_trace_const_cmp2+0x1c/0x30
[   57.748372]  ? __sanitizer_cov_trace_const_cmp4+0x1a/0x20
[   57.748391]  vfs_mkdir+0x6d1/0xbe0
[   57.748409]  do_mkdirat+0x48e/0x610
[   57.748424]  ? __pfx_do_mkdirat+0x10/0x10
[   57.748434]  ? strncpy_from_user+0x198/0x290
[   57.748473]  ? __sanitizer_cov_trace_const_cmp4+0x1a/0x20
[   57.748490]  ? do_getname+0x19e/0x3e0
[   57.748503]  __x64_sys_mkdir+0x70/0x90
[   57.748515]  x64_sys_call+0x1f87/0x21b0
[   57.748540]  do_syscall_64+0x6d/0x1180
[   57.748560]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   57.748572] RIP: 0033:0x7f0700a3e7bb
[   57.748596] Code: 73 01 c3 48 8b 0d 65 b6 1b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f8
[   57.748607] RSP: 002b:00007ffd03360d18 EFLAGS: 00000206 ORIG_RAX: 0000000000000053
[   57.748625] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f0700a3e7bb
[   57.748635] RDX: 0000000000000000 RSI: 00000000000001ff RDI: 00007ffd03360d20
[   57.748641] RBP: 00007ffd03360d60 R08: 0000000000000000 R09: 00007ffd03360ab5
[   57.748648] R10: 0000000000000169 R11: 0000000000000206 R12: 00007ffd03360e88
[   57.748655] R13: 0000000000401bd1 R14: 0000000000403e08 R15: 00007f0700d78000
[   57.748686]  </TASK>
[   57.767776] ------------[ cut here ]------------
[   57.768140] WARNING: kernel/rcu/tree_plugin.h:443 at __rcu_read_unlock+0x2da/0x620, CPU#1: repro/663
[   57.768917] Modules linked in:
[   57.769205] CPU: 1 UID: 0 PID: 663 Comm: repro Not tainted 6.19.0-rc5-next-20260113-0f853ca2a798 #1 PREEMPT(lazy)
[   57.770002] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org4
[   57.770904] RIP: 0010:__rcu_read_unlock+0x2da/0x620
[   57.771347] Code: c7 43 58 01 00 00 00 bf 09 00 00 00 e8 9f d2 d9 ff 4d 85 f6 0f 84 13 fe ff ff e8 21 10 29 00 fb 0f0
[   57.772820] RSP: 0018:ffff88801a1cf958 EFLAGS: 00010286
[   57.773242] RAX: 00000000ffffffff RBX: ffff88801c31cb00 RCX: ffffffff8167cc23
[   57.773815] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff88801c31d33c
[   57.774380] RBP: ffff88801a1cf980 R08: 0000000000000000 R09: fffffbfff0eaed8c
[   57.774950] R10: 0000000080000001 R11: 6162206b63617473 R12: ffff88801c31cb00
[   57.775556] R13: ffff88801c31cb00 R14: 0000000000000001 R15: 0000000000000001
[   57.776114] FS:  00007f0700d2b740(0000) GS:ffff8880e317a000(0000) knlGS:0000000000000000
[   57.776749] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   57.777196] CR2: 00000000313712d8 CR3: 00000000174b6005 CR4: 0000000000770ef0
[   57.777760] PKRU: 55555554
[   57.777996] Call Trace:
[   57.778206]  <TASK>
[   57.778848]  __wait_on_freeing_inode+0x144/0x3b0
[   57.779549]  ? __pfx___wait_on_freeing_inode+0x10/0x10
[   57.780006]  ? do_raw_spin_lock+0x140/0x280
[   57.780785]  ? __pfx_var_wake_function+0x10/0x10
[   57.781516]  ? __this_cpu_preempt_check+0x21/0x30
[   57.782096]  ? lock_is_held_type+0xef/0x150
[   57.783066]  insert_inode_locked+0x26c/0x860
[   57.784411]  __ext4_new_inode+0x1c4a/0x5230
[   57.786492]  ? __pfx___ext4_new_inode+0x10/0x10
[   57.787249]  ? __pfx___dquot_initialize+0x10/0x10
[   57.787692]  ? ext4_lookup+0xe7/0x710
[   57.788736]  ? __this_cpu_preempt_check+0x21/0x30
[   57.789906]  ext4_mkdir+0x360/0xb70
[   57.791512]  ? __pfx_ext4_mkdir+0x10/0x10
[   57.791878]  ? security_inode_permission+0xb8/0x220
[   57.792653]  ? inode_permission+0x39d/0x690
[   57.793027]  ? __sanitizer_cov_trace_const_cmp2+0x1c/0x30
[   57.793494]  ? __sanitizer_cov_trace_const_cmp4+0x1a/0x20
[   57.794522]  vfs_mkdir+0x6d1/0xbe0
[   57.795734]  do_mkdirat+0x48e/0x610
[   57.796959]  ? __pfx_do_mkdirat+0x10/0x10
[   57.797316]  ? strncpy_from_user+0x198/0x290
[   57.798228]  ? __sanitizer_cov_trace_const_cmp4+0x1a/0x20
[   57.798770]  ? do_getname+0x19e/0x3e0
[   57.799756]  __x64_sys_mkdir+0x70/0x90
[   57.800330]  x64_sys_call+0x1f87/0x21b0
[   57.800783]  do_syscall_64+0x6d/0x1180
[   57.801468]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   57.801912] RIP: 0033:0x7f0700a3e7bb
[   57.802246] Code: 73 01 c3 48 8b 0d 65 b6 1b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f8
[   57.803723] RSP: 002b:00007ffd03360d18 EFLAGS: 00000206 ORIG_RAX: 0000000000000053
[   57.804334] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f0700a3e7bb
[   57.804903] RDX: 0000000000000000 RSI: 00000000000001ff RDI: 00007ffd03360d20
[   57.805473] RBP: 00007ffd03360d60 R08: 0000000000000000 R09: 00007ffd03360ab5
[   57.806030] R10: 0000000000000169 R11: 0000000000000206 R12: 00007ffd03360e88
[   57.806599] R13: 0000000000401bd1 R14: 0000000000403e08 R15: 00007f0700d78000
[   57.808920]  </TASK>
[   57.809108] irq event stamp: 253367
[   57.809384] hardirqs last  enabled at (253367): [<ffffffff85f3bbe5>] _raw_spin_unlock_irqrestore+0x35/0x70
[   57.810226] hardirqs last disabled at (253366): [<ffffffff85f3b890>] _raw_spin_lock_irqsave+0x70/0x80
[   57.810996] softirqs last  enabled at (253362): [<ffffffff8131c2e1>] kernel_fpu_end+0x71/0x90
[   57.811769] softirqs last disabled at (253360): [<ffffffff8131db8f>] kernel_fpu_begin_mask+0x1df/0x320
[   57.812549] ---[ end trace 0000000000000000 ]---
"

Hope this cound be insightful to you.

Regards,
Yi Lai

---

If you don't need the following environment to reproduce the problem or if you
already have one reproduced environment, please ignore the following information.

How to reproduce:
git clone https://gitlab.com/xupengfe/repro_vm_env.git
cd repro_vm_env
tar -xvf repro_vm_env.tar.gz
cd repro_vm_env; ./start3.sh  // it needs qemu-system-x86_64 and I used v7.1.0
  // start3.sh will load bzImage_2241ab53cbb5cdb08a6b2d4688feb13971058f65 v6.2-rc5 kernel
  // You could change the bzImage_xxx as you want
  // Maybe you need to remove line "-drive if=pflash,format=raw,readonly=on,file=./OVMF_CODE.fd \" for different qemu version
You could use below command to log in, there is no password for root.
ssh -p 10023 root@...alhost

After login vm(virtual machine) successfully, you could transfer reproduced
binary to the vm by below way, and reproduce the problem in vm:
gcc -pthread -o repro repro.c
scp -P 10023 repro root@...alhost:/root/

Get the bzImage for target kernel:
Please use target kconfig and copy it to kernel_src/.config
make olddefconfig
make -jx bzImage           //x should equal or less than cpu num your pc has

Fill the bzImage file into above start3.sh to load the target kernel in vm.


Tips:
If you already have qemu-system-x86_64, please ignore below info.
If you want to install qemu v7.1.0 version:
git clone https://github.com/qemu/qemu.git
cd qemu
git checkout -f v7.1.0
mkdir build
cd build
yum install -y ninja-build.x86_64
yum -y install libslirp-devel.x86_64
../configure --target-list=x86_64-softmmu --enable-kvm --enable-vnc --enable-gtk --enable-sdl --enable-usb-redir --enable-slirp
make
make install 
 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ