lkml.org 
[lkml]   [2021]   [Sep]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.14 118/334] media: rockchip/rga: fix error handling in probe
    Date
    From: Dan Carpenter <dan.carpenter@oracle.com>

    [ Upstream commit e58430e1d4fd01b74475d2fbe2e25b5817b729a9 ]

    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: f7e7b48e6d79 ("[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>
    ---
    drivers/media/platform/rockchip/rga/rga.c | 27 ++++++++++++++++++-----
    1 file changed, 22 insertions(+), 5 deletions(-)

    diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
    index bf3fd71ec3af..6759091b15e0 100644
    --- a/drivers/media/platform/rockchip/rga/rga.c
    +++ b/drivers/media/platform/rockchip/rga/rga.c
    @@ -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;
    @@ -882,11 +882,23 @@ 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;
    @@ -894,7 +906,7 @@ static int rga_probe(struct platform_device *pdev)
    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",
    @@ -902,10 +914,15 @@ static int rga_probe(struct platform_device *pdev)

    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:
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-09-13 16:37    [W:4.132 / U:0.276 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site