Reviewed-by: Jianan Huang <[email protected]>

Thanks,
Jianan

在 2026年5月22日星期五,Gao Xiang <[email protected]> 写道:

> z_erofs_decompress_kickoff() can race with filesystem unmount, causing
> a use-after-free on sbi->sync_decompress.
>
> When I/O completes, z_erofs_endio() calls z_erofs_decompress_kickoff()
> to queue z_erofs_decompressqueue_work() asynchronously. Then, after all
> folios are unlocked, unmount workflow can proceed and sbi will be freed
> before accessing to sbi->sync_decompress.
>
> Thread (unmount)        I/O completion        kworker
>                         queue_work
>                                               z_erofs_decompressqueue_work
>                                                (all folios are unlocked)
> cleanup_mnt
>  ..
>  erofs_kill_sb
>   erofs_sb_free
>    kfree(sbi)
>                         access sbi->sync_decompress  // UAF!!
>
> Fixes: 40452ffca3c1 ("erofs: add sysfs node to control sync decompression
> strategy")
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=52bae5c495dbe261a0bc
> Signed-off-by: Gao Xiang <[email protected]>
> ---
>  fs/erofs/zdata.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
> index 27ab7bd844ec..c6240dccbb0f 100644
> --- a/fs/erofs/zdata.c
> +++ b/fs/erofs/zdata.c
> @@ -1455,6 +1455,9 @@ static void z_erofs_decompress_kickoff(struct
> z_erofs_decompressqueue *io,
>         if (atomic_add_return(bios, &io->pending_bios))
>                 return;
>         if (z_erofs_in_atomic()) {
> +               /* See `sync_decompress` in sysfs-fs-erofs for more
> details */
> +               if (sbi->sync_decompress == EROFS_SYNC_DECOMPRESS_AUTO)
> +                       sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_
> ON;
>  #ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
>                 struct kthread_worker *worker;
>
> @@ -1471,9 +1474,6 @@ static void z_erofs_decompress_kickoff(struct
> z_erofs_decompressqueue *io,
>  #else
>                 queue_work(z_erofs_workqueue, &io->u.work);
>  #endif
> -               /* See `sync_decompress` in sysfs-fs-erofs for more
> details */
> -               if (sbi->sync_decompress == EROFS_SYNC_DECOMPRESS_AUTO)
> -                       sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_
> ON;
>                 return;
>         }
>         gfp_flag = memalloc_noio_save();
> --
> 2.43.5
>
>
>

Reply via email to