diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-09-22 16:40:56 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-09-22 16:40:56 +0100 |
commit | edf6ea6fbe793b017a9765b493d7b1675a16a42f (patch) | |
tree | 6c975cd910a5c2b74cc4ba77b2a070c40b3807ca /hw | |
parent | 834b9273d5cdab68180dc8c84d641aaa4344b057 (diff) | |
parent | 1be90ebecc95b09a2ee5af3f60c412b45a766c4f (diff) | |
download | qemu-edf6ea6fbe793b017a9765b493d7b1675a16a42f.zip qemu-edf6ea6fbe793b017a9765b493d7b1675a16a42f.tar.gz qemu-edf6ea6fbe793b017a9765b493d7b1675a16a42f.tar.bz2 |
Merge remote-tracking branch 'remotes/kraxel/tags/usb-20200921-pull-request' into staging
usb: fix u2f build
usb: fix ohci oob access and loop issues
# gpg: Signature made Mon 21 Sep 2020 09:58:06 BST
# gpg: using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138
* remotes/kraxel/tags/usb-20200921-pull-request:
hw: usb: hcd-ohci: check for processed TD before retire
hw: usb: hcd-ohci: check len and frame_number variables
usb: fix u2f build
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/usb/hcd-ohci.c | 28 | ||||
-rw-r--r-- | hw/usb/u2f-emulated.c | 4 |
2 files changed, 28 insertions, 4 deletions
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 1e6e85e..8b912e9 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -691,6 +691,10 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, the next ISO TD of the same ED */ trace_usb_ohci_iso_td_relative_frame_number_big(relative_frame_number, frame_count); + if (OHCI_CC_DATAOVERRUN == OHCI_BM(iso_td.flags, TD_CC)) { + /* avoid infinite loop */ + return 1; + } OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN); ed->head &= ~OHCI_DPTR_MASK; ed->head |= (iso_td.next & OHCI_DPTR_MASK); @@ -731,7 +735,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, } start_offset = iso_td.offset[relative_frame_number]; - next_offset = iso_td.offset[relative_frame_number + 1]; + if (relative_frame_number < frame_count) { + next_offset = iso_td.offset[relative_frame_number + 1]; + } else { + next_offset = iso_td.be; + } if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) || ((relative_frame_number < frame_count) && @@ -764,7 +772,12 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, } } else { /* Last packet in the ISO TD */ - end_addr = iso_td.be; + end_addr = next_offset; + } + + if (start_addr > end_addr) { + trace_usb_ohci_iso_td_bad_cc_overrun(start_addr, end_addr); + return 1; } if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) { @@ -773,6 +786,9 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, } else { len = end_addr - start_addr + 1; } + if (len > sizeof(ohci->usb_buf)) { + len = sizeof(ohci->usb_buf); + } if (len && dir != OHCI_TD_DIR_IN) { if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, @@ -975,8 +991,16 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) { len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff); } else { + if (td.cbp > td.be) { + trace_usb_ohci_iso_td_bad_cc_overrun(td.cbp, td.be); + ohci_die(ohci); + return 1; + } len = (td.be - td.cbp) + 1; } + if (len > sizeof(ohci->usb_buf)) { + len = sizeof(ohci->usb_buf); + } pktlen = len; if (len && dir != OHCI_TD_DIR_IN) { diff --git a/hw/usb/u2f-emulated.c b/hw/usb/u2f-emulated.c index 9e1b829..9151feb 100644 --- a/hw/usb/u2f-emulated.c +++ b/hw/usb/u2f-emulated.c @@ -200,7 +200,7 @@ static ssize_t u2f_emulated_read(const char *path, char *buffer, int fd; ssize_t ret; - fd = qemu_open(path, O_RDONLY); + fd = qemu_open_old(path, O_RDONLY); if (fd < 0) { return -1; } @@ -217,7 +217,7 @@ static bool u2f_emulated_setup_counter(const char *path, int fd, ret; FILE *fp; - fd = qemu_open(path, O_RDWR); + fd = qemu_open_old(path, O_RDWR); if (fd < 0) { return false; } |