diff options
Diffstat (limited to 'hw/usb')
| -rw-r--r-- | hw/usb/bus.c | 4 | ||||
| -rw-r--r-- | hw/usb/dev-audio.c | 2 | ||||
| -rw-r--r-- | hw/usb/dev-mtp.c | 97 | ||||
| -rw-r--r-- | hw/usb/hcd-ohci.c | 7 | ||||
| -rw-r--r-- | hw/usb/trace-events | 22 |
5 files changed, 67 insertions, 65 deletions
diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 6fffab7bfa..9a74dc9560 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -500,6 +500,10 @@ static void usb_mask_to_str(char *dest, size_t size, speeds[i].name); } } + + if (pos == 0) { + snprintf(dest, size, "unknown"); + } } void usb_check_attach(USBDevice *dev, Error **errp) diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 28ac7c5165..c46d5eeb79 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -650,7 +650,7 @@ static void usb_audio_realize(USBDevice *dev, Error **errp) s->out.vol[1] = 240; /* 0 dB */ s->out.as.freq = USBAUDIO_SAMPLE_RATE; s->out.as.nchannels = 2; - s->out.as.fmt = AUD_FMT_S16; + s->out.as.fmt = AUDIO_FORMAT_S16; s->out.as.endianness = 0; streambuf_init(&s->out.buf, s->buffer); diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 06e376bcd2..99548b012d 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -170,7 +170,7 @@ struct MTPObject { char *path; struct stat stat; /* file monitor watch id */ - int watchid; + int64_t watchid; MTPObject *parent; uint32_t nchildren; QLIST_HEAD(, MTPObject) children; @@ -498,7 +498,7 @@ static MTPObject *usb_mtp_object_lookup_name(MTPObject *parent, return NULL; } -static MTPObject *usb_mtp_object_lookup_id(MTPState *s, int id) +static MTPObject *usb_mtp_object_lookup_id(MTPState *s, int64_t id) { MTPObject *iter; @@ -511,7 +511,7 @@ static MTPObject *usb_mtp_object_lookup_id(MTPState *s, int id) return NULL; } -static void file_monitor_event(int id, +static void file_monitor_event(int64_t id, QFileMonitorEvent ev, const char *name, void *opaque) @@ -625,8 +625,8 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o) } if (s->file_monitor) { - int id = qemu_file_monitor_add_watch(s->file_monitor, o->path, NULL, - file_monitor_event, s, &err); + int64_t id = qemu_file_monitor_add_watch(s->file_monitor, o->path, NULL, + file_monitor_event, s, &err); if (id == -1) { error_report("usb-mtp: failed to add watch for %s: %s", o->path, error_get_pretty(err)); @@ -1135,28 +1135,25 @@ static MTPData *usb_mtp_get_object_prop_value(MTPState *s, MTPControl *c, return d; } -/* Return correct return code for a delete event */ +/* + * Return values when object @o is deleted. + * If at least one of the deletions succeeded, + * DELETE_SUCCESS is set and if at least one + * of the deletions failed, DELETE_FAILURE is + * set. Both bits being set (DELETE_PARTIAL) + * signifies a RES_PARTIAL_DELETE being sent + * back to the initiator. + */ enum { - ALL_DELETE, - PARTIAL_DELETE, - READ_ONLY, + DELETE_SUCCESS = (1 << 0), + DELETE_FAILURE = (1 << 1), + DELETE_PARTIAL = (DELETE_FAILURE | DELETE_SUCCESS), }; -/* Assumes that children, if any, have been already freed */ -static void usb_mtp_object_free_one(MTPState *s, MTPObject *o) -{ - assert(o->nchildren == 0); - QTAILQ_REMOVE(&s->objects, o, next); - g_free(o->name); - g_free(o->path); - g_free(o); -} - static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) { MTPObject *iter, *iter2; - bool partial_delete = false; - bool success = false; + int ret = 0; /* * TODO: Add support for Protection Status @@ -1165,34 +1162,28 @@ static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) QLIST_FOREACH(iter, &o->children, list) { if (iter->format == FMT_ASSOCIATION) { QLIST_FOREACH(iter2, &iter->children, list) { - usb_mtp_deletefn(s, iter2, trans); + ret |= usb_mtp_deletefn(s, iter2, trans); } } } if (o->format == FMT_UNDEFINED_OBJECT) { if (remove(o->path)) { - partial_delete = true; + ret |= DELETE_FAILURE; } else { - usb_mtp_object_free_one(s, o); - success = true; + usb_mtp_object_free(s, o); + ret |= DELETE_SUCCESS; } } else if (o->format == FMT_ASSOCIATION) { if (rmdir(o->path)) { - partial_delete = true; + ret |= DELETE_FAILURE; } else { - usb_mtp_object_free_one(s, o); - success = true; + usb_mtp_object_free(s, o); + ret |= DELETE_SUCCESS; } } - if (success && partial_delete) { - return PARTIAL_DELETE; - } - if (!success && partial_delete) { - return READ_ONLY; - } - return ALL_DELETE; + return ret; } static void usb_mtp_object_delete(MTPState *s, uint32_t handle, @@ -1226,19 +1217,24 @@ static void usb_mtp_object_delete(MTPState *s, uint32_t handle, } ret = usb_mtp_deletefn(s, o, trans); - if (ret == PARTIAL_DELETE) { - usb_mtp_queue_result(s, RES_PARTIAL_DELETE, - trans, 0, 0, 0, 0); - return; - } else if (ret == READ_ONLY) { - usb_mtp_queue_result(s, RES_STORE_READ_ONLY, trans, - 0, 0, 0, 0); - return; - } else { + switch (ret) { + case DELETE_SUCCESS: usb_mtp_queue_result(s, RES_OK, trans, 0, 0, 0, 0); - return; + break; + case DELETE_FAILURE: + usb_mtp_queue_result(s, RES_PARTIAL_DELETE, + trans, 0, 0, 0, 0); + break; + case DELETE_PARTIAL: + usb_mtp_queue_result(s, RES_PARTIAL_DELETE, + trans, 0, 0, 0, 0); + break; + default: + g_assert_not_reached(); } + + return; } static void usb_mtp_command(MTPState *s, MTPControl *c) @@ -1703,12 +1699,19 @@ static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen) MTPObject *o; MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle); uint32_t next_handle = s->next_handle; + size_t filename_chars = dlen - offsetof(ObjectInfo, filename); + + /* + * filename is utf-16. We're intentionally doing + * integer division to truncate if malicious guest + * sent an odd number of bytes. + */ + filename_chars /= 2; assert(!s->write_pending); assert(p != NULL); - filename = utf16_to_str(MIN(dataset->length, - dlen - offsetof(ObjectInfo, filename)), + filename = utf16_to_str(MIN(dataset->length, filename_chars), dataset->filename); if (strchr(filename, '/')) { diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 196a9f7200..81cf5ab7a5 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -1200,7 +1200,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) if (head == 0) return 0; - for (cur = head; cur; cur = next_ed) { + for (cur = head; cur && link_cnt++ < ED_LINK_LIMIT; cur = next_ed) { if (ohci_read_ed(ohci, cur, &ed)) { trace_usb_ohci_ed_read_error(cur); ohci_die(ohci); @@ -1209,11 +1209,6 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) next_ed = ed.next & OHCI_DPTR_MASK; - if (++link_cnt > ED_LINK_LIMIT) { - ohci_die(ohci); - return 0; - } - if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) { uint32_t addr; /* Cancel pending packets for ED that have been paused. */ diff --git a/hw/usb/trace-events b/hw/usb/trace-events index 99b1e8b8ce..2d3713351c 100644 --- a/hw/usb/trace-events +++ b/hw/usb/trace-events @@ -1,16 +1,16 @@ # See docs/devel/tracing.txt for syntax documentation. -# hw/usb/core.c +# core.c usb_packet_state_change(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s -> %s" usb_packet_state_fault(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s, expected %s" -# hw/usb/bus.c +# bus.c usb_port_claim(int bus, const char *port) "bus %d, port %s" usb_port_attach(int bus, const char *port, const char *devspeed, const char *portspeed) "bus %d, port %s, devspeed %s, portspeed %s" usb_port_detach(int bus, const char *port) "bus %d, port %s" usb_port_release(int bus, const char *port) "bus %d, port %s" -# hw/usb/hcd-ohci.c +# hcd-ohci.c usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at 0x%x" usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count 0x%.8x relative %d" usb_ohci_iso_td_head_offset(uint32_t o0, uint32_t o1, uint32_t o2, uint32_t o3, uint32_t o4, uint32_t o5, uint32_t o6, uint32_t o7) "0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x" @@ -67,7 +67,7 @@ usb_ohci_init_time(int64_t frametime, int64_t bittime) "usb_bit_time=%" PRId64 " usb_ohci_die(void) "" usb_ohci_async_complete(void) "" -# hw/usb/hcd-ehci.c +# hcd-ehci.c usb_ehci_reset(void) "=== RESET ===" usb_ehci_unrealize(void) "=== UNREALIZE ===" usb_ehci_opreg_read(uint32_t addr, const char *str, uint32_t val) "rd mmio 0x%04x [%s] = 0x%x" @@ -100,7 +100,7 @@ usb_ehci_doorbell_ring(void) "" usb_ehci_doorbell_ack(void) "" usb_ehci_dma_error(void) "" -# hw/usb/hcd-uhci.c +# hcd-uhci.c usb_uhci_reset(void) "=== RESET ===" usb_uhci_exit(void) "=== EXIT ===" usb_uhci_schedule_start(void) "" @@ -130,7 +130,7 @@ usb_uhci_td_nextqh(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x" usb_uhci_td_async(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x" usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x" -# hw/usb/hcd-xhci.c +# hcd-xhci.c usb_xhci_reset(void) "=== RESET ===" usb_xhci_exit(void) "=== EXIT ===" usb_xhci_run(void) "" @@ -176,7 +176,7 @@ usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d" usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)" usb_xhci_enforced_limit(const char *item) "%s" -# hw/usb/desc.c +# desc.c usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d" usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d" usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d" @@ -190,7 +190,7 @@ usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d" usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d" -# hw/usb/dev-hub.c +# dev-hub.c usb_hub_reset(int addr) "dev %d" usb_hub_control(int addr, int request, int value, int index, int length) "dev %d, req 0x%x, value %d, index %d, langth %d" usb_hub_get_port_status(int addr, int nr, int status, int changed) "dev %d, port %d, status 0x%x, changed 0x%x" @@ -200,7 +200,7 @@ usb_hub_attach(int addr, int nr) "dev %d, port %d" usb_hub_detach(int addr, int nr) "dev %d, port %d" usb_hub_status_report(int addr, int status) "dev %d, status 0x%x" -# hw/usb/dev-uas.c +# dev-uas.c usb_uas_reset(int addr) "dev %d" usb_uas_command(int addr, uint16_t tag, int lun, uint32_t lun64_1, uint32_t lun64_2) "dev %d, tag 0x%x, lun %d, lun64 0x%08x-0x%08x" usb_uas_response(int addr, uint16_t tag, uint8_t code) "dev %d, tag 0x%x, code 0x%x" @@ -214,7 +214,7 @@ usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag) "dev %d, tag 0 usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) "dev %d, tag 0x%x, lun %d" usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) "dev %d, tag 0x%x, function 0x%x" -# hw/usb/dev-mtp.c +# dev-mtp.c usb_mtp_reset(int addr) "dev %d" usb_mtp_command(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x, 0x%x, 0x%x, 0x%x" usb_mtp_success(int dev, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, trans 0x%x, args 0x%x, 0x%x" @@ -239,7 +239,7 @@ usb_mtp_object_free(int dev, uint32_t handle, const char *path) "dev %d, handle usb_mtp_add_child(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s" usb_mtp_file_monitor_event(int dev, const char *path, const char *s) "dev %d, path %s event %s" -# hw/usb/host-libusb.c +# host-libusb.c usb_host_open_started(int bus, int addr) "dev %d:%d" usb_host_open_success(int bus, int addr) "dev %d:%d" usb_host_open_failure(int bus, int addr) "dev %d:%d" |