On Thu, Jun 02, 2022 at 06:39:30PM +0800, Michael Wu wrote: > On 6/1/2022 12:15 PM, Linyu Yuan wrote: > > In ffs_epfile_io(), when read/write data in blocking mode, it will wait > > the completion in interruptible mode, if task receive a signal, it will > > terminate the wait, at same time, if function unbind occurs, > > ffs_func_unbind() will kfree all eps, ffs_epfile_io() still try to > > dequeue request by dereferencing ep which may become invalid. > > > > Fix it by add ep spinlock and will not dereference ep if it is not valid. > > > > Reported-by: Michael Wu <michael@xxxxxxxxxxxxxxxxx> > > Reviewed-by: John Keeping <john@xxxxxxxxxxxx> > > Signed-off-by: Linyu Yuan <quic_linyyuan@xxxxxxxxxxx> > > --- > > v2: add Reviewed-by from John keeping > > v3: add Reported-by from Michael Wu > > > > drivers/usb/gadget/function/f_fs.c | 6 ++++++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c > > index d4d8940..9bf9287 100644 > > --- a/drivers/usb/gadget/function/f_fs.c > > +++ b/drivers/usb/gadget/function/f_fs.c > > @@ -1077,6 +1077,11 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) > > spin_unlock_irq(&epfile->ffs->eps_lock); > > if (wait_for_completion_interruptible(&io_data->done)) { > > + spin_lock_irq(&epfile->ffs->eps_lock); > > + if (epfile->ep != ep) { > > + ret = -ESHUTDOWN; > > + goto error_lock; > > + } > > /* > > * To avoid race condition with ffs_epfile_io_complete, > > * dequeue the request first then check > > @@ -1084,6 +1089,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) > > * condition with req->complete callback. > > */ > > usb_ep_dequeue(ep->ep, req); > > + spin_unlock_irq(&epfile->ffs->eps_lock); > > wait_for_completion(&io_data->done); > > interrupted = io_data->status < 0; > > } > > Tested-by: Michael Wu <michael@xxxxxxxxxxxxxxxxx> > > I've tested Linyu's patches [PATCH v3 1/2] [PATCH v3 2/2]. I believe it > fixes the bug I reported. > > What's more, John's solution [1] also works in my tests. It looks simpler. > I'm not sure if it's as complete as Linyu's solution. It's not as comprehensive, let's focus on this thread. > [1] https://lore.kernel.org/linux-usb/YpUJkxWBNuZiW7Xk@donbot/