Daniel P. Berrangé <berra...@redhat.com> writes: > The ObjectInfo struct has a variable length array containing the UTF-16 > encoded filename. The number of characters of trailing data is given by > the 'length' field in the struct and this must be validated against the > size of the data packet received from the guest. > > Since the data is UTF-16, we must convert the byte count we have to a > character count before validating. This must take care to truncate if > a malicious guest sent an odd number of bytes. > > Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> > --- > hw/usb/dev-mtp.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c > index 838cd74da6..6b7d1296e4 100644 > --- a/hw/usb/dev-mtp.c > +++ b/hw/usb/dev-mtp.c > @@ -1699,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, '/')) {
Reviewed-by: Bandan Das <b...@redhat.com>