aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBandan Das <bsd@redhat.com>2019-03-06 16:04:07 -0500
committerGerd Hoffmann <kraxel@redhat.com>2019-03-07 10:02:48 +0100
commitc5ead51f90cf33ccf07974eba5154be2af2c7fc3 (patch)
treea30e7809ea5c6292bfd4b663380071b5b871523e
parent32694e98b8d7a246345448a8f707d2e11d6c65e2 (diff)
usb-mtp: return incomplete transfer on a lstat failure
MTP writes objects in small chunks and at the end gets the real file size to update the object metadata. If this fails for any reason, return an INCOMPLETE_TRANSFER to the initiator Spotted by Coverity: CID 1398651 Signed-off-by: Bandan Das <bsd@redhat.com> Message-id: 20190306210409.14842-2-bsd@redhat.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/usb/dev-mtp.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 4ee4fc5a89..4dde14fc78 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1591,14 +1591,18 @@ done:
return ret;
}
-static void usb_mtp_update_object(MTPObject *parent, char *name)
+static int usb_mtp_update_object(MTPObject *parent, char *name)
{
+ int ret = -1;
+
MTPObject *o =
usb_mtp_object_lookup_name(parent, name, strlen(name));
if (o) {
- lstat(o->path, &o->stat);
+ ret = lstat(o->path, &o->stat);
}
+
+ return ret;
}
static void usb_mtp_write_data(MTPState *s)
@@ -1655,13 +1659,18 @@ static void usb_mtp_write_data(MTPState *s)
if (d->write_status != WRITE_END) {
return;
} else {
- /* Only for < 4G file sizes */
- if (s->dataset.size != 0xFFFFFFFF && d->offset != s->dataset.size) {
+ /*
+ * Return an incomplete transfer if file size doesn't match
+ * for < 4G file or if lstat fails which will result in an incorrect
+ * file size
+ */
+ if ((s->dataset.size != 0xFFFFFFFF &&
+ d->offset != s->dataset.size) ||
+ usb_mtp_update_object(parent, s->dataset.filename)) {
usb_mtp_queue_result(s, RES_INCOMPLETE_TRANSFER, d->trans,
0, 0, 0, 0);
goto done;
}
- usb_mtp_update_object(parent, s->dataset.filename);
}
}