diff options
author | Prasad J Pandit <pjp@fedoraproject.org> | 2016-01-20 01:26:46 +0530 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2016-03-22 17:40:40 -0500 |
commit | 4dcd2f13b1bf7f23a587d0e832ff30d2da6291a1 (patch) | |
tree | 49c2393d379db5702d1c5266b3e7d9d54f41780e | |
parent | 38e09211b6ab29a21788a39166ded08c1724879d (diff) | |
download | hqemu-4dcd2f13b1bf7f23a587d0e832ff30d2da6291a1.zip hqemu-4dcd2f13b1bf7f23a587d0e832ff30d2da6291a1.tar.gz |
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)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r-- | hw/usb/hcd-ehci.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index d2b7fa2..60de088 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1405,21 +1405,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); |