Re: [PATCH] btrfs: lock balance status ioctls against shutdown
From: David Sterba
Date: Tue May 12 2026 - 10:04:34 EST
On Tue, May 12, 2026 at 08:10:58PM +0930, Qu Wenruo wrote:
> > do not pin the superblock against shutdown and they do not reject a
> > dying superblock before taking balance_mutex.
> >
> > During unmount, btrfs_put_super() runs close_ctree(), which pauses
> > balance and tears down filesystem state, and btrfs_kill_super() later
> > frees fs_info. If a balance status/control ioctl races with that
> > teardown, it can enter mutex locking on a stale balance_mutex. The
> > optimistic mutex spin path only tolerates speculative owner reads while
> > the mutex object itself remains valid, so a stale mutex can surface as
> > the observed task_struct UAF in owner_on_cpu().
> >
> > [FIX]
> > Take s_umount in read mode around BALANCE_CTL and BALANCE_PROGRESS, and
> > bail out once the superblock is already dying. This gives the read-only
> > balance status ioctls a shutdown barrier without changing their
> > semantics to require a writable mount.
>
> Why not just follow btrfs_ioctl_balance() to take mnt_want_write_file()?
>
> Balance is always a read-write operation, there is no read-only balance.
> Thus I think it's completely fine to call mnt_want_write_file() even for
> btrfs_ioctl_balance_progress() and btrfs_ioctl_balance_ctl().
>
> And this avoids unnecessary low-level access to s_umount.
Not just s_umount, mnt_want_write_file() also handles fs freezing and
other internal VFS things, the S_* state is not enough.