mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-26 22:38:07 -05:00
50 lines
2 KiB
Diff
50 lines
2 KiB
Diff
|
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||
|
Date: Wed, 20 Jan 2016 01:26:46 +0530
|
||
|
Subject: [PATCH] usb: check page select value while processing iTD
|
||
|
|
||
|
While processing isochronous transfer descriptors(iTD), the page
|
||
|
select(PG) field value could lead to an OOB read access. Add
|
||
|
check to avoid it.
|
||
|
|
||
|
Reported-by: Qinghao Tang <luodalongde@gmail.com>
|
||
|
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||
|
Message-id: 1453233406-12165-1-git-send-email-ppandit@redhat.com
|
||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||
|
(cherry picked from commit 49d925ce50383a286278143c05511d30ec41a36e)
|
||
|
---
|
||
|
hw/usb/hcd-ehci.c | 10 ++++++----
|
||
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
|
||
|
index d07f228..c40013e 100644
|
||
|
--- a/hw/usb/hcd-ehci.c
|
||
|
+++ b/hw/usb/hcd-ehci.c
|
||
|
@@ -1404,21 +1404,23 @@ static int ehci_process_itd(EHCIState *ehci,
|
||
|
if (itd->transact[i] & ITD_XACT_ACTIVE) {
|
||
|
pg = get_field(itd->transact[i], ITD_XACT_PGSEL);
|
||
|
off = itd->transact[i] & ITD_XACT_OFFSET_MASK;
|
||
|
- ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
|
||
|
- ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
|
||
|
len = get_field(itd->transact[i], ITD_XACT_LENGTH);
|
||
|
|
||
|
if (len > max * mult) {
|
||
|
len = max * mult;
|
||
|
}
|
||
|
-
|
||
|
- if (len > BUFF_SIZE) {
|
||
|
+ if (len > BUFF_SIZE || pg > 6) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
+ ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
|
||
|
qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
|
||
|
if (off + len > 4096) {
|
||
|
/* transfer crosses page border */
|
||
|
+ if (pg == 6) {
|
||
|
+ return -1; /* avoid page pg + 1 */
|
||
|
+ }
|
||
|
+ ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
|
||
|
uint32_t len2 = off + len - 4096;
|
||
|
uint32_t len1 = len - len2;
|
||
|
qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
|