diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-10-24 18:15:53 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2013-11-26 09:21:17 +0100 |
commit | 3453f9a0dfa58578e6dadf0905ff4528b428ec73 (patch) | |
tree | 881e103470634f3a1c2225739dfcdffb86c1bc36 /hw/usb/dev-uas.c | |
parent | 0478661ec5f949f16a70687b348c0fb2a56cc537 (diff) |
uas: Bounds check tags when using streams
Disallow the guest to cause us to address the data3 and status3 arrays
out of bounds.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb/dev-uas.c')
-rw-r--r-- | hw/usb/dev-uas.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index 70f41d390a..5884035df3 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -692,6 +692,9 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui) uint32_t len; uint16_t tag = be16_to_cpu(ui->hdr.tag); + if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) { + goto invalid_tag; + } req = usb_uas_find_request(uas, tag); if (req) { goto overlapped_tag; @@ -724,6 +727,10 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui) } return; +invalid_tag: + usb_uas_queue_fake_sense(uas, tag, sense_code_INVALID_TAG); + return; + overlapped_tag: usb_uas_queue_fake_sense(uas, tag, sense_code_OVERLAPPED_COMMANDS); return; @@ -742,6 +749,9 @@ static void usb_uas_task(UASDevice *uas, uas_ui *ui) UASRequest *req; uint16_t task_tag; + if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) { + goto invalid_tag; + } req = usb_uas_find_request(uas, be16_to_cpu(ui->hdr.tag)); if (req) { goto overlapped_tag; @@ -774,6 +784,10 @@ static void usb_uas_task(UASDevice *uas, uas_ui *ui) } return; +invalid_tag: + usb_uas_queue_response(uas, tag, UAS_RC_INVALID_INFO_UNIT, 0); + return; + overlapped_tag: usb_uas_queue_response(uas, req->tag, UAS_RC_OVERLAPPED_TAG, 0); return; |