Re: gadgetfs inode.c - possible memory corruption ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



But can't be this a deadlock ?
What if IRQ which calls complete(...) will be executed sooner than
wait_for_completion()

št 7. 7. 2022 o 18:11 Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> napísal(a):
>
> On Thu, Jul 07, 2022 at 11:43:09AM +0200, Jozo M. wrote:
> > Hello,
> >
> > my kernel running on imx6 was crashing on USB gadgetfs because my
> > kernel was using wait_event API instead of completion (I was convinced
> > it is due to wrong HW setup).
> > During research gadgetfs inode.c function ep_io was not clear for me:
> >
> > we are submiting USB request here
> >       value = usb_ep_queue (epdata->ep, req, GFP_ATOMIC);
> > then we are waiting for completion here:
> >       value = wait_for_completion_interruptible(&done);
> > but if completion is interrupted we end up here:
> >       spin_unlock_irq (&epdata->dev->lock);
> >       DBG (epdata->dev, "endpoint gone\n");
> >       epdata->status = -ENODEV;
>
> You left out part of the code.  We end up at this code in the case where
> epdata->ep == NULL, and the only way that can happen is if the endpoint
> was removed while we were waiting for the completion.
>
> > At this point ep_io is terminated and stack is not valid. Later on
> > epio_complete might be called from IRQ and it calls complete ((struct
> > completion *)req->context) but stack is no longer valid;
> > Shouldn't we put req->context = NULL;  before spin_unlock_irq
> > (&epdata->dev->lock); ?
> >       req->context = NULL;
> >       spin_unlock_irq (&epdata->dev->lock);
> >       DBG (epdata->dev, "endpoint gone\n");
> >       epdata->status = -ENODEV;
>
> You're right that this is a bug, but your solution is not correct.
> There is a race: epio_complete can run at the same time as this code if
> the endpoint is removed concurrently with the interrupt, and your
> approach is still subject to this race.
>
> The right way to fix the problem is to call wait_for_completion(&done)
> between the DBG and the assignment to epdata->status.  That way the
> stack will still be valid when epio_complete runs.
>
> Please feel free to submit a patch doing this.
>
> Alan Stern




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux