lkml.org 
[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 055/239] media: dmxdev: fix UAF when dvb_register_device() fails
    Date
    From: Wang Hai <wanghai38@huawei.com>

    [ Upstream commit ab599eb11882f834951c436cc080c3455ba32b9b ]

    I got a use-after-free report:

    dvbdev: dvb_register_device: failed to create device dvb1.dvr0 (-12)
    ...
    ==================================================================
    BUG: KASAN: use-after-free in dvb_dmxdev_release+0xce/0x2f0
    ...
    Call Trace:
    dump_stack_lvl+0x6c/0x8b
    print_address_description.constprop.0+0x48/0x70
    kasan_report.cold+0x82/0xdb
    __asan_load4+0x6b/0x90
    dvb_dmxdev_release+0xce/0x2f0
    ...
    Allocated by task 7666:
    kasan_save_stack+0x23/0x50
    __kasan_kmalloc+0x83/0xa0
    kmem_cache_alloc_trace+0x22e/0x470
    dvb_register_device+0x12f/0x980
    dvb_dmxdev_init+0x1f3/0x230
    ...
    Freed by task 7666:
    kasan_save_stack+0x23/0x50
    kasan_set_track+0x20/0x30
    kasan_set_free_info+0x24/0x40
    __kasan_slab_free+0xf2/0x130
    kfree+0xd1/0x5c0
    dvb_register_device.cold+0x1ac/0x1fa
    dvb_dmxdev_init+0x1f3/0x230
    ...

    When dvb_register_device() in dvb_dmxdev_init() fails, dvb_dmxdev_init()
    does not return a failure, and the memory pointed to by dvbdev or
    dvr_dvbdev is invalid at this point. If they are used subsequently, it
    will result in UFA or null-ptr-deref.

    If dvb_register_device() in dvb_dmxdev_init() fails, fix the bug by making
    dvb_dmxdev_init() return an error as well.

    Link: https://lore.kernel.org/linux-media/20211015085741.1203283-1-wanghai38@huawei.com

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Reported-by: Hulk Robot <hulkci@huawei.com>
    Signed-off-by: Wang Hai <wanghai38@huawei.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/media/dvb-core/dmxdev.c | 18 +++++++++++++++---
    1 file changed, 15 insertions(+), 3 deletions(-)

    diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
    index d548f98c7a67d..9e0ef3934fa3d 100644
    --- a/drivers/media/dvb-core/dmxdev.c
    +++ b/drivers/media/dvb-core/dmxdev.c
    @@ -1412,7 +1412,7 @@ static const struct dvb_device dvbdev_dvr = {
    };
    int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
    {
    - int i;
    + int i, ret;

    if (dmxdev->demux->open(dmxdev->demux) < 0)
    return -EUSERS;
    @@ -1431,14 +1431,26 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
    DMXDEV_STATE_FREE);
    }

    - dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
    + ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
    DVB_DEVICE_DEMUX, dmxdev->filternum);
    - dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
    + if (ret < 0)
    + goto err_register_dvbdev;
    +
    + ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
    dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
    + if (ret < 0)
    + goto err_register_dvr_dvbdev;

    dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);

    return 0;
    +
    +err_register_dvr_dvbdev:
    + dvb_unregister_device(dmxdev->dvbdev);
    +err_register_dvbdev:
    + vfree(dmxdev->filter);
    + dmxdev->filter = NULL;
    + return ret;
    }

    EXPORT_SYMBOL(dvb_dmxdev_init);
    --
    2.34.1


    \
     
     \ /
      Last update: 2022-01-24 21:09    [W:4.036 / U:0.836 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site