[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] usb: fix serial generator
From: |
Thomas Huth |
Subject: |
Re: [Qemu-devel] [PATCH] usb: fix serial generator |
Date: |
Wed, 5 Oct 2016 11:50:24 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
On 05.10.2016 11:33, Gerd Hoffmann wrote:
> snprintf return value is *not* the number of chars written into the
> buffer, but the number of chars needed. So in case the buffer is too
> small you can go alloc a bigger one and try again. But that also means
> you can't simply use the return value for the next snprintf call
> without checking beforehand that things did actually fit.
>
> Problem is that usb_desc_create_serial didn't perform that check, so a
> loooong path string (can happen with deep pci-bridge nesting) results in
> the third snprintf call smashing the stack.
>
> Fix this by throwing out all the snpintf calls and use g_strdup_printf
> instead.
>
> https://bugzilla.redhat.com/show_bug.cgi?id=1381630
>
> Reported-by: Thomas Huth <address@hidden>
> Signed-off-by: Gerd Hoffmann <address@hidden>
> ---
> hw/usb/desc.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/hw/usb/desc.c b/hw/usb/desc.c
> index 5e0e1d1..7828e52 100644
> --- a/hw/usb/desc.c
> +++ b/hw/usb/desc.c
> @@ -556,9 +556,7 @@ void usb_desc_create_serial(USBDevice *dev)
> DeviceState *hcd = dev->qdev.parent_bus->parent;
> const USBDesc *desc = usb_device_get_usb_desc(dev);
> int index = desc->id.iSerialNumber;
> - char serial[64];
> - char *path;
> - int dst;
> + char *path, *serial;
>
> if (dev->serial) {
> /* 'serial' usb bus property has priority if present */
> @@ -567,14 +565,16 @@ void usb_desc_create_serial(USBDevice *dev)
> }
>
> assert(index != 0 && desc->str[index] != NULL);
> - dst = snprintf(serial, sizeof(serial), "%s", desc->str[index]);
> path = qdev_get_dev_path(hcd);
> if (path) {
> - dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", path);
> + serial = g_strdup_printf("%s-%s-%s", desc->str[index],
> + path, dev->port->path);
> + } else {
> + serial = g_strdup_printf("%s-%s", desc->str[index], dev->port->path);
> }
> - dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);
> usb_desc_set_string(dev, index, serial);
> g_free(path);
> + g_free(serial);
> }
>
> const char *usb_desc_get_string(USBDevice *dev, uint8_t index)
Reviewed-by: Thomas Huth <address@hidden>