Re: [PATCH] usb: gadget: f_mass_storage: take filesem in nofua store to fix backing-file UAF
From: Alan Stern
Date: Sun Oct 18 2026 - 11:51:08 EST
On Sun, Oct 18, 2026 at 11:05:19PM +1000, Yu Zhang wrote:
> fsg_store_nofua() syncs the LUN's backing file when switching from async
> to sync mode:
>
> if (!nofua && curlun->nofua)
> fsg_lun_fsync_sub(curlun);
>
> fsg_lun_fsync_sub() dereferences curlun->filp (vfs_fsync(filp)). Unlike
> every other store that touches the backing file -- fsg_store_ro() and
> fsg_store_cdrom() (down_read), fsg_store_file() (down_write) --
> fsg_store_nofua() holds no filesem while doing so.
> diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c
> index 0000003..0000004 100644
> --- a/drivers/usb/gadget/function/storage_common.c
> +++ b/drivers/usb/gadget/function/storage_common.c
> @@ -415,7 +415,8 @@
> }
> EXPORT_SYMBOL_GPL(fsg_store_ro);
>
> -ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
> +ssize_t fsg_store_nofua(struct fsg_lun *curlun, struct rw_semaphore *filesem,
> + const char *buf, size_t count)
> {
> bool nofua;
> int ret;
> @@ -424,11 +425,13 @@
> if (ret)
> return ret;
>
> + down_read(filesem);
> /* Sync data when switching from async mode to sync */
> if (!nofua && curlun->nofua)
> fsg_lun_fsync_sub(curlun);
>
> curlun->nofua = nofua;
> + up_read(filesem);
Shouldn't filesem be held only within the body of the conditional?
There's no reason to take it if fsg_lun_fsync_sub() isn't going to be
called.
Alan Stern