Commit ef5d5641 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20160419-1' into staging



ehci: fix (s)iTD looping issue (CVE-2015-8558) in a different way.

# gpg: Signature made Tue 19 Apr 2016 07:22:22 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-usb-20160419-1:
  Revert "ehci: make idt processing more robust"
  ehci: apply limit to iTD/sidt descriptors

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents bb97bfd9 a49923d2
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -1397,7 +1397,7 @@ static int ehci_process_itd(EHCIState *ehci,
{
    USBDevice *dev;
    USBEndpoint *ep;
    uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
    uint32_t i, len, pid, dir, devaddr, endp;
    uint32_t pg, off, ptr1, ptr2, max, mult;

    ehci->periodic_sched_active = PERIODIC_ACTIVE;
@@ -1489,10 +1489,9 @@ static int ehci_process_itd(EHCIState *ehci,
                ehci_raise_irq(ehci, USBSTS_INT);
            }
            itd->transact[i] &= ~ITD_XACT_ACTIVE;
            xfers++;
        }
    }
    return xfers ? 0 : -1;
    return 0;
}


@@ -2011,6 +2010,7 @@ static int ehci_state_writeback(EHCIQueue *q)
static void ehci_advance_state(EHCIState *ehci, int async)
{
    EHCIQueue *q = NULL;
    int itd_count = 0;
    int again;

    do {
@@ -2035,10 +2035,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)

        case EST_FETCHITD:
            again = ehci_state_fetchitd(ehci, async);
            itd_count++;
            break;

        case EST_FETCHSITD:
            again = ehci_state_fetchsitd(ehci, async);
            itd_count++;
            break;

        case EST_ADVANCEQUEUE:
@@ -2087,7 +2089,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
            break;
        }

        if (again < 0) {
        if (again < 0 || itd_count > 16) {
            /* TODO: notify guest (raise HSE irq?) */
            fprintf(stderr, "processing error - resetting ehci HC\n");
            ehci_reset(ehci);
            again = 0;