aboutsummaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorMichael Hanselmann <public@hansmi.ch>2018-12-13 22:37:06 +0000
committerGerd Hoffmann <kraxel@redhat.com>2018-12-14 08:57:17 +0100
commit90c1a74271ce4667d16eeca575dfa78a6c7d465c (patch)
treeeaf9de9bb8605ef17ace6c80cd5fb781f092016d /hw/usb
parentbab9df35ce73d1c8e19a37e2737717ea1c984dc1 (diff)
downloadqemu-90c1a74271ce4667d16eeca575dfa78a6c7d465c.zip
qemu-90c1a74271ce4667d16eeca575dfa78a6c7d465c.tar.gz
qemu-90c1a74271ce4667d16eeca575dfa78a6c7d465c.tar.bz2
usb-mtp: Limit filename to object information size
The filename length in MTP metadata is specified by the guest. By trusting it directly it'd theoretically be possible to get the host to write memory parts outside the filename buffer into a filename. In practice though there are usually NUL bytes stopping the string operations. Also use the opportunity to not assign the filename member twice. Signed-off-by: Michael Hanselmann <public@hansmi.ch> Message-id: ab70659d8d5c580bdf150a5f7d5cc60c8e374ffc.1544740018.git.public@hansmi.ch [ kraxel: codestyle fix: break a long line ] Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/dev-mtp.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 36c43b8..6098005 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1710,7 +1710,7 @@ free:
s->write_pending = false;
}
-static void usb_mtp_write_metadata(MTPState *s)
+static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
{
MTPData *d = s->data_out;
ObjectInfo *dataset = (ObjectInfo *)d->data;
@@ -1722,7 +1722,9 @@ static void usb_mtp_write_metadata(MTPState *s)
assert(!s->write_pending);
assert(p != NULL);
- filename = utf16_to_str(dataset->length, dataset->filename);
+ filename = utf16_to_str(MIN(dataset->length,
+ dlen - offsetof(ObjectInfo, filename)),
+ dataset->filename);
if (strchr(filename, '/')) {
usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,
@@ -1738,7 +1740,6 @@ static void usb_mtp_write_metadata(MTPState *s)
s->dataset.filename = filename;
s->dataset.format = dataset->format;
s->dataset.size = dataset->size;
- s->dataset.filename = filename;
s->write_pending = true;
if (s->dataset.format == FMT_ASSOCIATION) {
@@ -1807,7 +1808,7 @@ static void usb_mtp_get_data(MTPState *s, mtp_container *container,
if (d->offset == d->length) {
/* The operation might have already failed */
if (!s->result) {
- usb_mtp_write_metadata(s);
+ usb_mtp_write_metadata(s, dlen);
}
usb_mtp_data_free(s->data_out);
s->data_out = NULL;