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

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJXFc6eAAoJEEy22O7T6HE4jOsQAInCKNSK7UbHEqAxcNt9v9jB
 7wrv87tiNYRQrFE46oLcvQdVfggW0Dml2xX8Isrmm44DKd7pZzliklHqlAIiyX2Z
 KyjrEjpTLJ3hMAHD9UbiCg4u69W4gWNTGhHtzYUCfRMwTfIawhKwUSce61ZscZEo
 Brb9hJa6mPULSey7LvFTlqEAH9qMiKTV53jZ4t/mcBNwICtOmPzxoQkegNxoFP6u
 k0gHdI9V2uwfDGlnyXKY38CytE08C+JB2CL4OggGeF6VFZDxeYZJc6pEiGhepFyE
 PPt5blBNyHxPvYXtCJp+K94IfhJB2iDGuBFL8SuMVtmE6FGDKGlCgZrV32TcCxxU
 nDK7hdbhz3wnpvlcc5L5xXe3bAyFyasWQ5BGtamgwyG/U+3WYm9A+j5nNXyI8f3A
 IWfR84XfuynNIHn+eCrHZHkby7x+U9IQ2yeb/2vwUj4ddGGo2nCnqjqVnh2CFWoW
 HWPLhQi0sjCN2/Sfokxh8Dm9lTDrUTz5tyZhPQUw4xzrpPdDbkQkAruO9MJmulRz
 D24s8AObL4s/0CKRbN/U3dzE9oxqJ0V++zGbdPyg8QFaPczXruGSrHCPxQjY3rto
 JEjNanI01Nl0TcA7EquTxjVsZdeGSEGuhBnx7qJO2LtjMbcOrHZg4vGXIyI1Oc6N
 F0RYHVSQibOwLG0r9pQi
 =Y5Gl
 -----END PGP SIGNATURE-----

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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-04-19 12:10:30 +01:00
commit ef5d5641f5

View File

@ -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;