Skip to content

Commit

Permalink
media: rockchip/rga: fix error handling in probe
Browse files Browse the repository at this point in the history
[ Upstream commit e58430e ]

There are a few bugs in this code.  1)  No checks for whether
dma_alloc_attrs() or __get_free_pages() failed.  2)  If
video_register_device() fails it doesn't clean up the dma attrs or the
free pages.  3)  The video_device_release() function frees "vfd" which
leads to a use after free on the next line.  The call to
video_unregister_device() is not required so I have just removed that.

Fixes: f7e7b48 ("[media] rockchip/rga: v4l2 m2m support")
Reported-by: Dongliang Mu <mudongliangabcd@gmail.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Dan Carpenter authored and gregkh committed Sep 15, 2021
1 parent 71135cf commit 82a1b7e
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions drivers/media/platform/rockchip/rga/rga.c
Expand Up @@ -863,12 +863,12 @@ static int rga_probe(struct platform_device *pdev)
if (IS_ERR(rga->m2m_dev)) {
v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n");
ret = PTR_ERR(rga->m2m_dev);
goto unreg_video_dev;
goto rel_vdev;
}

ret = pm_runtime_resume_and_get(rga->dev);
if (ret < 0)
goto unreg_video_dev;
goto rel_vdev;

rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
Expand All @@ -882,30 +882,47 @@ static int rga_probe(struct platform_device *pdev)
rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE,
&rga->cmdbuf_phy, GFP_KERNEL,
DMA_ATTR_WRITE_COMBINE);
if (!rga->cmdbuf_virt) {
ret = -ENOMEM;
goto rel_vdev;
}

rga->src_mmu_pages =
(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
if (!rga->src_mmu_pages) {
ret = -ENOMEM;
goto free_dma;
}
rga->dst_mmu_pages =
(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
if (rga->dst_mmu_pages) {
ret = -ENOMEM;
goto free_src_pages;
}

def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
def_frame.size = def_frame.stride * def_frame.height;

ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
if (ret) {
v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
goto rel_vdev;
goto free_dst_pages;
}

v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n",
vfd->name, video_device_node_name(vfd));

return 0;

free_dst_pages:
free_pages((unsigned long)rga->dst_mmu_pages, 3);
free_src_pages:
free_pages((unsigned long)rga->src_mmu_pages, 3);
free_dma:
dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt,
rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
rel_vdev:
video_device_release(vfd);
unreg_video_dev:
video_unregister_device(rga->vfd);
unreg_v4l2_dev:
v4l2_device_unregister(&rga->v4l2_dev);
err_put_clk:
Expand Down

0 comments on commit 82a1b7e

Please sign in to comment.