Skip to content

Commit

Permalink
usb-mtp: return incomplete transfer on a lstat failure
Browse files Browse the repository at this point in the history
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 <[email protected]>
Message-id: [email protected]
Signed-off-by: Gerd Hoffmann <[email protected]>
  • Loading branch information
whitebrandy authored and kraxel committed Mar 7, 2019
1 parent 32694e9 commit c5ead51
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions hw/usb/dev-mtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1591,14 +1591,18 @@ static uint64_t write_retry(int fd, void *buf, uint64_t size, off_t offset)
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)
Expand Down Expand Up @@ -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);
}
}

Expand Down

0 comments on commit c5ead51

Please sign in to comment.