From b75dc14a9410f57b3f7853854da013af86fb87c2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 6 May 2016 13:25:14 +0200 Subject: [PATCH] testo: Fix USB device list leak The testo driver uses libusb_get_device_list() but neglects to call the matching libusb_device_list_free() on the error path. This will leak the memory allocated for the list as well as all the devices. To address the issue use sr_usb_open() instead of open-coding its functionality. sr_usb_open() correctly handles freeing the device list. The issue was discovered using the following coccinelle semantic patch: // @@ identifier devlist; expression ctx, ret; statement S; @@ ( libusb_get_device_list(ctx, &devlist); | ret = libusb_get_device_list(ctx, &devlist); if (ret < 0) S ) ... when != libusb_free_device_list(devlist, ...) *return ...; // Signed-off-by: Lars-Peter Clausen --- src/hardware/testo/api.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/hardware/testo/api.c b/src/hardware/testo/api.c index 9a984cdc..a6146e08 100644 --- a/src/hardware/testo/api.c +++ b/src/hardware/testo/api.c @@ -150,27 +150,13 @@ static int dev_open(struct sr_dev_inst *sdi) struct sr_dev_driver *di = sdi->driver; struct drv_context *drvc = di->context; struct sr_usb_dev_inst *usb; - libusb_device **devlist; - int ret, i; - char connection_id[64]; + int ret; usb = sdi->conn; - libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); - for (i = 0; devlist[i]; i++) { - usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); - if (strcmp(sdi->connection_id, connection_id)) - continue; - if ((ret = libusb_open(devlist[i], &usb->devhdl))) { - sr_err("Failed to open device: %s.", libusb_error_name(ret)); - return SR_ERR; - } - break; - } - libusb_free_device_list(devlist, 1); - if (!devlist[i]) { - sr_err("Device not found."); - return SR_ERR; - } + + ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb); + if (ret != SR_OK) + return ret; if (libusb_has_capability(LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) { if (libusb_kernel_driver_active(usb->devhdl, 0) == 1) {