remoteproc: Fix a memory leak in an error handling path in 'rproc_handle_vdev()'
authorChristophe JAILLET <christophe.jaillet@wanadoo.fr>
Sat, 4 Sep 2021 11:37:32 +0000 (13:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Nov 2021 18:17:01 +0000 (19:17 +0100)
[ Upstream commit 0374a4ea7269645c46c3eb288526ea072fa19e79 ]

If 'copy_dma_range_map() fails, the memory allocated for 'rvdev' will leak.
Move the 'copy_dma_range_map()' call after the device registration so
that 'rproc_rvdev_release()' can be called to free some resources.

Also, branch to the error handling path if 'copy_dma_range_map()' instead
of a direct return to avoid some other leaks.

Fixes: e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Jim Quinlan <james.quinlan@broadcom.com>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/e6d0dad6620da4fdf847faa903f79b735d35f262.1630755377.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/remoteproc/remoteproc_core.c

index 502b660..775df16 100644 (file)
@@ -556,9 +556,6 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
        /* Initialise vdev subdevice */
        snprintf(name, sizeof(name), "vdev%dbuffer", rvdev->index);
        rvdev->dev.parent = &rproc->dev;
-       ret = copy_dma_range_map(&rvdev->dev, rproc->dev.parent);
-       if (ret)
-               return ret;
        rvdev->dev.release = rproc_rvdev_release;
        dev_set_name(&rvdev->dev, "%s#%s", dev_name(rvdev->dev.parent), name);
        dev_set_drvdata(&rvdev->dev, rvdev);
@@ -568,6 +565,11 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
                put_device(&rvdev->dev);
                return ret;
        }
+
+       ret = copy_dma_range_map(&rvdev->dev, rproc->dev.parent);
+       if (ret)
+               goto free_rvdev;
+
        /* Make device dma capable by inheriting from parent's capabilities */
        set_dma_ops(&rvdev->dev, get_dma_ops(rproc->dev.parent));