lkml.org 
[lkml]   [2022]   [Oct]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.9 01/10] media: cx88: Fix a null-ptr-deref bug in buffer_prepare()
    Date
    From: Zheyu Ma <zheyuma97@gmail.com>

    [ Upstream commit 2b064d91440b33fba5b452f2d1b31f13ae911d71 ]

    When the driver calls cx88_risc_buffer() to prepare the buffer, the
    function call may fail, resulting in a empty buffer and null-ptr-deref
    later in buffer_queue().

    The following log can reveal it:

    [ 41.822762] general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI
    [ 41.824488] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
    [ 41.828027] RIP: 0010:buffer_queue+0xc2/0x500
    [ 41.836311] Call Trace:
    [ 41.836945] __enqueue_in_driver+0x141/0x360
    [ 41.837262] vb2_start_streaming+0x62/0x4a0
    [ 41.838216] vb2_core_streamon+0x1da/0x2c0
    [ 41.838516] __vb2_init_fileio+0x981/0xbc0
    [ 41.839141] __vb2_perform_fileio+0xbf9/0x1120
    [ 41.840072] vb2_fop_read+0x20e/0x400
    [ 41.840346] v4l2_read+0x215/0x290
    [ 41.840603] vfs_read+0x162/0x4c0

    Fix this by checking the return value of cx88_risc_buffer()

    [hverkuil: fix coding style issues]

    Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
    Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/media/pci/cx88/cx88-vbi.c | 9 +++---
    drivers/media/pci/cx88/cx88-video.c | 43 +++++++++++++++--------------
    2 files changed, 26 insertions(+), 26 deletions(-)

    diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
    index d3237cf8ffa3..78d78b7c974c 100644
    --- a/drivers/media/pci/cx88/cx88-vbi.c
    +++ b/drivers/media/pci/cx88/cx88-vbi.c
    @@ -140,11 +140,10 @@ static int buffer_prepare(struct vb2_buffer *vb)
    return -EINVAL;
    vb2_set_plane_payload(vb, 0, size);

    - cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
    - 0, VBI_LINE_LENGTH * lines,
    - VBI_LINE_LENGTH, 0,
    - lines);
    - return 0;
    + return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
    + 0, VBI_LINE_LENGTH * lines,
    + VBI_LINE_LENGTH, 0,
    + lines);
    }

    static void buffer_finish(struct vb2_buffer *vb)
    diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
    index 3b140ad598de..0ad0f4ab6c4b 100644
    --- a/drivers/media/pci/cx88/cx88-video.c
    +++ b/drivers/media/pci/cx88/cx88-video.c
    @@ -443,6 +443,7 @@ static int queue_setup(struct vb2_queue *q,

    static int buffer_prepare(struct vb2_buffer *vb)
    {
    + int ret;
    struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
    struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
    struct cx88_core *core = dev->core;
    @@ -457,42 +458,42 @@ static int buffer_prepare(struct vb2_buffer *vb)

    switch (core->field) {
    case V4L2_FIELD_TOP:
    - cx88_risc_buffer(dev->pci, &buf->risc,
    - sgt->sgl, 0, UNSET,
    - buf->bpl, 0, core->height);
    + ret = cx88_risc_buffer(dev->pci, &buf->risc,
    + sgt->sgl, 0, UNSET,
    + buf->bpl, 0, core->height);
    break;
    case V4L2_FIELD_BOTTOM:
    - cx88_risc_buffer(dev->pci, &buf->risc,
    - sgt->sgl, UNSET, 0,
    - buf->bpl, 0, core->height);
    + ret = cx88_risc_buffer(dev->pci, &buf->risc,
    + sgt->sgl, UNSET, 0,
    + buf->bpl, 0, core->height);
    break;
    case V4L2_FIELD_SEQ_TB:
    - cx88_risc_buffer(dev->pci, &buf->risc,
    - sgt->sgl,
    - 0, buf->bpl * (core->height >> 1),
    - buf->bpl, 0,
    - core->height >> 1);
    + ret = cx88_risc_buffer(dev->pci, &buf->risc,
    + sgt->sgl,
    + 0, buf->bpl * (core->height >> 1),
    + buf->bpl, 0,
    + core->height >> 1);
    break;
    case V4L2_FIELD_SEQ_BT:
    - cx88_risc_buffer(dev->pci, &buf->risc,
    - sgt->sgl,
    - buf->bpl * (core->height >> 1), 0,
    - buf->bpl, 0,
    - core->height >> 1);
    + ret = cx88_risc_buffer(dev->pci, &buf->risc,
    + sgt->sgl,
    + buf->bpl * (core->height >> 1), 0,
    + buf->bpl, 0,
    + core->height >> 1);
    break;
    case V4L2_FIELD_INTERLACED:
    default:
    - cx88_risc_buffer(dev->pci, &buf->risc,
    - sgt->sgl, 0, buf->bpl,
    - buf->bpl, buf->bpl,
    - core->height >> 1);
    + ret = cx88_risc_buffer(dev->pci, &buf->risc,
    + sgt->sgl, 0, buf->bpl,
    + buf->bpl, buf->bpl,
    + core->height >> 1);
    break;
    }
    dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
    buf, buf->vb.vb2_buf.index,
    core->width, core->height, dev->fmt->depth, dev->fmt->name,
    (unsigned long)buf->risc.dma);
    - return 0;
    + return ret;
    }

    static void buffer_finish(struct vb2_buffer *vb)
    --
    2.35.1
    \
     
     \ /
      Last update: 2022-10-13 02:46    [W:2.068 / U:0.844 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site