From 24e8d1faea1e4a2dc59841e048390645d7804cb5 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Thu, 3 May 2018 15:20:27 -0400 Subject: usb-mtp: Add some NULL checks for issues pointed out by coverity CID 1390578: In usb_mtp_write_metadata, parent can never be NULL but just in case, add an assert CID 1390592: Check for o->format only if o !=NULL CID 1390604: Check s->data_out != NULL in usb_mtp_handle_data Signed-off-by: Bandan Das Message-id: 20180503192028.14353-2-bsd@redhat.com Signed-off-by: Gerd Hoffmann --- hw/usb/dev-mtp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 6ecf70a79b..24cff640c0 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -1446,8 +1446,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) if (o == NULL) { usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, c->trans, 0, 0, 0, 0); - } - if (o->format != FMT_ASSOCIATION) { + } else if (o->format != FMT_ASSOCIATION) { usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT, c->trans, 0, 0, 0, 0); } @@ -1660,6 +1659,7 @@ static void usb_mtp_write_metadata(MTPState *s) uint32_t next_handle = s->next_handle; assert(!s->write_pending); + assert(p != NULL); utf16_to_str(dataset->length, dataset->filename, filename); @@ -1838,7 +1838,7 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p) p->status = USB_RET_STALL; return; } - if (s->data_out && !s->data_out->first) { + if ((s->data_out != NULL) && !s->data_out->first) { container_type = TYPE_DATA; } else { usb_packet_copy(p, &container, sizeof(container)); -- cgit v1.2.1 From 2392ae6bbb0a940a4fd6df29e704b09cadc14790 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Thu, 3 May 2018 15:20:28 -0400 Subject: usb-mtp: Unconditionally check for the readonly bit Currently, it's only being checked if desc is NULL and so write support breaks upon specifying desc Signed-off-by: Bandan Das Message-id: 20180503192028.14353-3-bsd@redhat.com Signed-off-by: Gerd Hoffmann --- hw/usb/dev-mtp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 24cff640c0..3d59fe4944 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -1948,16 +1948,17 @@ static void usb_mtp_realize(USBDevice *dev, Error **errp) return; } s->desc = strrchr(s->root, '/'); - /* Mark store as RW */ - if (!s->readonly) { - s->flags |= (1 << MTP_FLAG_WRITABLE); - } if (s->desc && s->desc[0]) { s->desc = g_strdup(s->desc + 1); } else { s->desc = g_strdup("none"); } } + /* Mark store as RW */ + if (!s->readonly) { + s->flags |= (1 << MTP_FLAG_WRITABLE); + } + } static const VMStateDescription vmstate_usb_mtp = { -- cgit v1.2.1 From 3280ea8edede3814553aa19fa27a58daedd48ad9 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 3 May 2018 08:29:32 +0200 Subject: usb-host: skip open on pending postload bh usb-host emulates a device unplug after live migration, because the device state is unknown and unplug/replug makes sure the guest re-initializes the device into a working state. This can't be done in post-load though, so post-load just schedules a bottom half which executes after vmload is complete. It can happen that the device autoscan timer hits the race window between scheduling and running the bottom half, which in turn can triggers an assert(). Fix that issue by just ignoring the usb_host_open() call in case the bottom half didn't execute yet. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1572851 Signed-off-by: Gerd Hoffmann Message-id: 20180503062932.17233-1-kraxel@redhat.com --- hw/usb/host-libusb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index dc0a8fe295..f31e9cbbb8 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -102,6 +102,7 @@ struct USBHostDevice { /* callbacks & friends */ QEMUBH *bh_nodev; QEMUBH *bh_postld; + bool bh_postld_pending; Notifier exit; /* request queues */ @@ -870,6 +871,10 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev) int rc; Error *local_err = NULL; + if (s->bh_postld_pending) { + return -1; + } + trace_usb_host_open_started(bus_num, addr); if (s->dh != NULL) { @@ -1528,6 +1533,7 @@ static void usb_host_post_load_bh(void *opaque) if (udev->attached) { usb_device_detach(udev); } + dev->bh_postld_pending = false; usb_host_auto_check(NULL); } @@ -1539,6 +1545,7 @@ static int usb_host_post_load(void *opaque, int version_id) dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev); } qemu_bh_schedule(dev->bh_postld); + dev->bh_postld_pending = true; return 0; } -- cgit v1.2.1