aboutsummaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-09-22 16:40:56 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-09-22 16:40:56 +0100
commitedf6ea6fbe793b017a9765b493d7b1675a16a42f (patch)
tree6c975cd910a5c2b74cc4ba77b2a070c40b3807ca /hw/usb
parent834b9273d5cdab68180dc8c84d641aaa4344b057 (diff)
parent1be90ebecc95b09a2ee5af3f60c412b45a766c4f (diff)
downloadqemu-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/usb')
-rw-r--r--hw/usb/hcd-ohci.c28
-rw-r--r--hw/usb/u2f-emulated.c4
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;
}