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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <aydmzeppdfhyuopcnzbdzmmrsdlb56dr5jae422h64guiklgpq@kzn2bb72jj4r>
Date: Fri, 16 Jan 2026 13:42:21 +0100
From: Jan Kara <jack@...e.cz>
To: Abhishek Bapat <abhishekbapat@...gle.com>
Cc: Jan Kara <jack@...e.com>, Christian Brauner <brauner@...nel.org>, 
	Jeremy Bongio <jbongio@...gle.com>, Khazhy Kumykov <khazhy@...gle.com>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] quota: fix livelock between quotactl and freeze_super

On Thu 15-01-26 21:31:03, Abhishek Bapat wrote:
> When a filesystem is frozen, quotactl_block() enters a retry loop
> waiting for the filesystem to thaw. It acquires s_umount, checks the
> freeze state, drops s_umount and uses sb_start_write() - sb_end_write()
> pair to wait for the unfreeze.
> 
> However, this retry loop can trigger a livelock issue, specifically on
> kernels with preemption disabled.
> 
> The mechanism is as follows:
> 1. freeze_super() sets SB_FREEZE_WRITE and calls sb_wait_write().
> 2. sb_wait_write() calls percpu_down_write(), which initiates
>    synchronize_rcu().
> 3. Simultaneously, quotactl_block() spins in its retry loop, immediately
>    executing the sb_start_write() - sb_end_write() pair.
> 4. Because the kernel is non-preemptible and the loop contains no
>    scheduling points, quotactl_block() never yields the CPU. This
>    prevents that CPU from reaching an RCU quiescent state.
> 5. synchronize_rcu() in the freezer thread waits indefinitely for the
>    quotactl_block() CPU to report a quiescent state.
> 6. quotactl_block() spins indefinitely waiting for the freezer to
>    advance, which it cannot do as it is blocked on the RCU sync.
> 
> This results in a hang of the freezer process and 100% CPU usage by the
> quota process.
> 
> While this can occur intermittently on multi-core systems, it is
> reliably reproducing on a node with the following script, running both
> the freezer and the quota toggle on the same CPU:
> 
>   # mkfs.ext4 -O quota /dev/sda 2g && mkdir a_mount
>   # mount /dev/sda -o quota,usrquota,grpquota a_mount
>   # taskset -c 3 bash -c "while true; do xfs_freeze -f a_mount; \
>     xfs_freeze -u a_mount; done" &
>   # taskset -c 3 bash -c "while true; do quotaon a_mount; \
>     quotaoff a_mount; done" &
> 
> Adding cond_resched() to the retry loop fixes the issue. It acts as an
> RCU quiescent state, allowing synchronize_rcu() in percpu_down_write()
> to complete.
> 
> Fixes: 576215cffdef ("fs: Drop wait_unfrozen wait queue")
> Signed-off-by: Abhishek Bapat <abhishekbapat@...gle.com>

Thanks for the fix! I've added it to my tree.

								Honza

> ---
>  fs/quota/quota.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> index 7c2b75a44485..de4379a9c792 100644
> --- a/fs/quota/quota.c
> +++ b/fs/quota/quota.c
> @@ -899,6 +899,7 @@ static struct super_block *quotactl_block(const char __user *special, int cmd)
>  		sb_start_write(sb);
>  		sb_end_write(sb);
>  		put_super(sb);
> +		cond_resched();
>  		goto retry;
>  	}
>  	return sb;
> -- 
> 2.52.0.457.g6b5491de43-goog
> 
-- 
Jan Kara <jack@...e.com>
SUSE Labs, CR

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ