staging: mmal-vchiq: Fix memory leak for vchiq_instance
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 26 Oct 2020 09:55:50 +0000 (18:55 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Oct 2020 12:19:01 +0000 (13:19 +0100)
The vchiq_instance is allocated with vchiq_initialise() but never
freed properly. Fix memory leak for the vchiq_instance.

Reported-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Link: https://lore.kernel.org/r/1603706150-10806-1-git-send-email-sw0312.kim@samsung.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c

index 3a42025..9097bcb 100644 (file)
@@ -179,6 +179,9 @@ struct vchiq_mmal_instance {
 
        /* ordered workqueue to process all bulk operations */
        struct workqueue_struct *bulk_wq;
+
+       /* handle for a vchiq instance */
+       struct vchiq_instance *vchiq_instance;
 };
 
 static struct mmal_msg_context *
@@ -1840,6 +1843,7 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
 
        mutex_unlock(&instance->vchiq_mutex);
 
+       vchiq_shutdown(instance->vchiq_instance);
        flush_workqueue(instance->bulk_wq);
        destroy_workqueue(instance->bulk_wq);
 
@@ -1856,6 +1860,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_finalise);
 int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
 {
        int status;
+       int err = -ENODEV;
        struct vchiq_mmal_instance *instance;
        static struct vchiq_instance *vchiq_instance;
        struct vchiq_service_params_kernel params = {
@@ -1890,17 +1895,21 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
        status = vchiq_connect(vchiq_instance);
        if (status) {
                pr_err("Failed to connect VCHI instance (status=%d)\n", status);
-               return -EIO;
+               err = -EIO;
+               goto err_shutdown_vchiq;
        }
 
        instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 
-       if (!instance)
-               return -ENOMEM;
+       if (!instance) {
+               err = -ENOMEM;
+               goto err_shutdown_vchiq;
+       }
 
        mutex_init(&instance->vchiq_mutex);
 
        instance->bulk_scratch = vmalloc(PAGE_SIZE);
+       instance->vchiq_instance = vchiq_instance;
 
        mutex_init(&instance->context_map_lock);
        idr_init_base(&instance->context_map, 1);
@@ -1932,7 +1941,9 @@ err_close_services:
 err_free:
        vfree(instance->bulk_scratch);
        kfree(instance);
-       return -ENODEV;
+err_shutdown_vchiq:
+       vchiq_shutdown(vchiq_instance);
+       return err;
 }
 EXPORT_SYMBOL_GPL(vchiq_mmal_init);