diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-08-08 12:41:38 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-08-08 12:41:38 +0100 |
commit | 9efaf7f5f5729f7fa8dcf413fabe3d46ad382f90 (patch) | |
tree | deb4bd2faa2a2707c11a2f6458d19d8d46269896 | |
parent | cbda16c010a2e1e7cd6e5441cef87663fbe1ef75 (diff) | |
parent | 5839df7b71540a2af2580bb53ad1e2005bb175e6 (diff) | |
download | qemu-9efaf7f5f5729f7fa8dcf413fabe3d46ad382f90.zip qemu-9efaf7f5f5729f7fa8dcf413fabe3d46ad382f90.tar.gz qemu-9efaf7f5f5729f7fa8dcf413fabe3d46ad382f90.tar.bz2 |
Merge remote-tracking branch 'remotes/elmarco/tags/leaks-for-2.7-pull-request' into staging
# gpg: Signature made Sun 07 Aug 2016 21:03:14 BST
# gpg: using RSA key 0xDAE8E10975969CE5
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>"
# gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5
* remotes/elmarco/tags/leaks-for-2.7-pull-request:
ahci: fix sglist leak on retry
usb: free leaking path
usb: free USBDevice.strings
virtio-input: free config list
qjson: free str
ahci: free irqs array
char: free MuxDriver when closing
char: free the tcp connection data when closing
numa: do not leak NumaOptions
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/ide/ahci.c | 4 | ||||
-rw-r--r-- | hw/ide/core.c | 1 | ||||
-rw-r--r-- | hw/input/virtio-input.c | 11 | ||||
-rw-r--r-- | hw/usb/bus.c | 7 | ||||
-rw-r--r-- | hw/usb/desc.c | 1 | ||||
-rw-r--r-- | migration/qjson.c | 1 | ||||
-rw-r--r-- | numa.c | 15 | ||||
-rw-r--r-- | qemu-char.c | 58 |
8 files changed, 70 insertions, 28 deletions
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index bcb9ff9..f3438ad 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -919,6 +919,7 @@ static void ncq_err(NCQTransferState *ncq_tfs) ide_state->error = ABRT_ERR; ide_state->status = READY_STAT | ERR_STAT; ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag); + qemu_sglist_destroy(&ncq_tfs->sglist); ncq_tfs->used = 0; } @@ -1025,7 +1026,6 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs) default: DPRINTF(port, "error: unsupported NCQ command (0x%02x) received\n", ncq_tfs->cmd); - qemu_sglist_destroy(&ncq_tfs->sglist); ncq_err(ncq_tfs); } } @@ -1092,7 +1092,6 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, error_report("ahci: PRDT length for NCQ command (0x%zx) " "is smaller than the requested size (0x%zx)", ncq_tfs->sglist.size, size); - qemu_sglist_destroy(&ncq_tfs->sglist); ncq_err(ncq_tfs); ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW); return; @@ -1478,6 +1477,7 @@ void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports) ad->port.dma->ops = &ahci_dma_ops; ide_register_restart_cb(&ad->port); } + g_free(irqs); } void ahci_uninit(AHCIState *s) diff --git a/hw/ide/core.c b/hw/ide/core.c index d117b7c..45b6df1 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -824,6 +824,7 @@ static void ide_dma_cb(void *opaque, int ret) if (ret < 0) { if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) { s->bus->dma->aiocb = NULL; + dma_buf_commit(s, 0); return; } } diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index a87fd68..ccdf730 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -270,6 +270,16 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); } +static void virtio_input_finalize(Object *obj) +{ + VirtIOInput *vinput = VIRTIO_INPUT(obj); + VirtIOInputConfig *cfg, *next; + + QTAILQ_FOREACH_SAFE(cfg, &vinput->cfg_list, node, next) { + QTAILQ_REMOVE(&vinput->cfg_list, cfg, node); + g_free(cfg); + } +} static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); @@ -318,6 +328,7 @@ static const TypeInfo virtio_input_info = { .class_size = sizeof(VirtIOInputClass), .class_init = virtio_input_class_init, .abstract = true, + .instance_finalize = virtio_input_finalize, }; /* ----------------------------------------------------------------- */ diff --git a/hw/usb/bus.c b/hw/usb/bus.c index c28ccb8..25913ad 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -279,6 +279,13 @@ static void usb_qdev_realize(DeviceState *qdev, Error **errp) static void usb_qdev_unrealize(DeviceState *qdev, Error **errp) { USBDevice *dev = USB_DEVICE(qdev); + USBDescString *s, *next; + + QLIST_FOREACH_SAFE(s, &dev->strings, next, next) { + QLIST_REMOVE(s, next); + g_free(s->str); + g_free(s); + } if (dev->attached) { usb_device_detach(dev); diff --git a/hw/usb/desc.c b/hw/usb/desc.c index adb026e..5e0e1d1 100644 --- a/hw/usb/desc.c +++ b/hw/usb/desc.c @@ -574,6 +574,7 @@ void usb_desc_create_serial(USBDevice *dev) } dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path); usb_desc_set_string(dev, index, serial); + g_free(path); } const char *usb_desc_get_string(USBDevice *dev, uint8_t index) diff --git a/migration/qjson.c b/migration/qjson.c index 5cae55a..f345904 100644 --- a/migration/qjson.c +++ b/migration/qjson.c @@ -109,5 +109,6 @@ void qjson_finish(QJSON *json) void qjson_destroy(QJSON *json) { + QDECREF(json->str); g_free(json); } @@ -223,14 +223,14 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) } if (err) { - goto error; + goto end; } switch (object->type) { case NUMA_OPTIONS_KIND_NODE: numa_node_parse(object->u.node.data, opts, &err); if (err) { - goto error; + goto end; } nb_numa_nodes++; break; @@ -238,13 +238,14 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) abort(); } - return 0; - -error: - error_report_err(err); +end: qapi_free_NumaOptions(object); + if (err) { + error_report_err(err); + return -1; + } - return -1; + return 0; } static char *enumerate_cpus(unsigned long *cpus, int max_cpus) diff --git a/qemu-char.c b/qemu-char.c index 27f2dbb..8a0ab05 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -786,6 +786,13 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) return d->drv->chr_add_watch(d->drv, cond); } +static void mux_chr_close(struct CharDriverState *chr) +{ + MuxDriver *d = chr->opaque; + + g_free(d); +} + static CharDriverState *qemu_chr_open_mux(const char *id, ChardevBackend *backend, ChardevReturn *ret, Error **errp) @@ -810,6 +817,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id, chr->opaque = d; d->drv = drv; d->focus = -1; + chr->chr_close = mux_chr_close; chr->chr_write = mux_chr_write; chr->chr_update_read_handler = mux_chr_update_read_handler; chr->chr_accept_input = mux_chr_accept_input; @@ -2763,6 +2771,7 @@ static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) /* clear old pending fd array */ g_free(s->write_msgfds); s->write_msgfds = NULL; + s->write_msgfds_num = 0; if (!s->connected || !qio_channel_has_feature(s->ioc, @@ -2843,19 +2852,24 @@ static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond) return qio_channel_create_watch(s->ioc, cond); } -static void tcp_chr_disconnect(CharDriverState *chr) +static void tcp_chr_free_connection(CharDriverState *chr) { TCPCharDriver *s = chr->opaque; + int i; if (!s->connected) { return; } - s->connected = 0; - if (s->listen_ioc) { - s->listen_tag = qio_channel_add_watch( - QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL); + if (s->read_msgfds_num) { + for (i = 0; i < s->read_msgfds_num; i++) { + close(s->read_msgfds[i]); + } + g_free(s->read_msgfds); + s->read_msgfds = NULL; + s->read_msgfds_num = 0; } + tcp_set_msgfds(chr, NULL, 0); remove_fd_in_watch(chr); object_unref(OBJECT(s->sioc)); @@ -2863,6 +2877,24 @@ static void tcp_chr_disconnect(CharDriverState *chr) object_unref(OBJECT(s->ioc)); s->ioc = NULL; g_free(chr->filename); + chr->filename = NULL; + s->connected = 0; +} + +static void tcp_chr_disconnect(CharDriverState *chr) +{ + TCPCharDriver *s = chr->opaque; + + if (!s->connected) { + return; + } + + tcp_chr_free_connection(chr); + + if (s->listen_ioc) { + s->listen_tag = qio_channel_add_watch( + QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL); + } chr->filename = SocketAddress_to_str("disconnected:", s->addr, s->is_listen, s->is_telnet); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); @@ -3177,17 +3209,14 @@ int qemu_chr_wait_connected(CharDriverState *chr, Error **errp) static void tcp_chr_close(CharDriverState *chr) { TCPCharDriver *s = chr->opaque; - int i; + + tcp_chr_free_connection(chr); if (s->reconnect_timer) { g_source_remove(s->reconnect_timer); s->reconnect_timer = 0; } qapi_free_SocketAddress(s->addr); - remove_fd_in_watch(chr); - if (s->ioc) { - object_unref(OBJECT(s->ioc)); - } if (s->listen_tag) { g_source_remove(s->listen_tag); s->listen_tag = 0; @@ -3195,18 +3224,9 @@ static void tcp_chr_close(CharDriverState *chr) if (s->listen_ioc) { object_unref(OBJECT(s->listen_ioc)); } - if (s->read_msgfds_num) { - for (i = 0; i < s->read_msgfds_num; i++) { - close(s->read_msgfds[i]); - } - g_free(s->read_msgfds); - } if (s->tls_creds) { object_unref(OBJECT(s->tls_creds)); } - if (s->write_msgfds_num) { - g_free(s->write_msgfds); - } g_free(s); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } |