>Number:         91629
>Category:       usb
>Synopsis:       usbd_abort_pipe() may result in infinite loop
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-usb
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 11 09:20:02 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Raaf
>Release:        FreeBSD 6.0-RELEASE i386
>Organization:
>Environment:
System: FreeBSD 6.0-RELEASE

        
>Description:
        Calling usbd_abort_pipe() may result in an infinite loop.

        usbd_abort_pipe() calls usbd_ar_pipe() which loops in getting
        transfers of the head of the pipe queue (but doesn't remove
        them) while the pipequeue isn't empty, and then calls
        pipe->methods->abort():
        
        while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
                pipe->methods->abort(xfer);
        }
        
        If the pipe is isochronous than pipe->methods->abort() can yield
        to ohci_device_isoc_abort or uhci_device_isoc_abort.

        The following code is at the begining of ohci_device_isoc_abort:
        
        /* Transfer is already done. */
        if (xfer->status != USBD_NOT_STARTED &&
            xfer->status != USBD_IN_PROGRESS) {
                splx(s);
                printf("ohci_device_isoc_abort: early return\n");
                return;
        }

        As you can see if this codepath is taken then the  transfer
        still isn't removed from the pipequeue with as result an
        infinite loop and a system that doesn't respond anymore.

>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to