@@ -1615,7 +1615,8 @@ static void iio_dev_release(struct device *device)
iio_device_detach_buffers(indio_dev);
- ida_simple_remove(&iio_ida, iio_dev_opaque->id);
+ if (iio_dev_opaque->id >= 0)
+ ida_simple_remove(&iio_ida, iio_dev_opaque->id);
kfree(iio_dev_opaque);
}
@@ -1662,20 +1663,20 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
if (iio_dev_opaque->id < 0) {
/* cannot use a dev_err as the name isn't available */
pr_err("failed to get device id\n");
- kfree(iio_dev_opaque);
- return NULL;
+ goto err_put_device;
}
- if (dev_set_name(&indio_dev->dev, "iio:device%d", iio_dev_opaque->id)) {
- ida_simple_remove(&iio_ida, iio_dev_opaque->id);
- kfree(iio_dev_opaque);
- return NULL;
- }
+ if (dev_set_name(&indio_dev->dev, "iio:device%d", iio_dev_opaque->id))
+ goto err_put_device;
INIT_LIST_HEAD(&iio_dev_opaque->buffer_list);
INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
return indio_dev;
+
+err_put_device:
+ put_device(&indio_dev->dev);
+ return NULL;
}
EXPORT_SYMBOL(iio_device_alloc);
Once device_initialize() has been called on a struct device the device must be freed by decreasing the reference count rather than directly freeing the underlying memory. This is so that any additional state and resources associated with the device get properly freed. In this particular case there are no additional resources associated with the device and no additional reference count. So there is no resource leak or use-after-free by freeing the struct device directly But in order to follow best practices and avoid accidental future breakage use put_device() instead of kfree() to free the device when an error occurs. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> --- No fixes tag since, while the code is wrong, it works. No leaks and no use-after-free. drivers/iio/industrialio-core.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)