qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

usb-mtp: fix bounds check for guest provided filename

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é <berrange@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

authored by

Daniel P. Berrangé and committed by
Peter Maydell
375cb86d dbfc49b6

+9 -2
+9 -2
hw/usb/dev-mtp.c
··· 1699 1699 MTPObject *o; 1700 1700 MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle); 1701 1701 uint32_t next_handle = s->next_handle; 1702 + size_t filename_chars = dlen - offsetof(ObjectInfo, filename); 1703 + 1704 + /* 1705 + * filename is utf-16. We're intentionally doing 1706 + * integer division to truncate if malicious guest 1707 + * sent an odd number of bytes. 1708 + */ 1709 + filename_chars /= 2; 1702 1710 1703 1711 assert(!s->write_pending); 1704 1712 assert(p != NULL); 1705 1713 1706 - filename = utf16_to_str(MIN(dataset->length, 1707 - dlen - offsetof(ObjectInfo, filename)), 1714 + filename = utf16_to_str(MIN(dataset->length, filename_chars), 1708 1715 dataset->filename); 1709 1716 1710 1717 if (strchr(filename, '/')) {