lkml.org 
[lkml]   [2022]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6.0 793/862] 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 a075788c64d4..469aeaa725ad 100644
    --- a/drivers/media/pci/cx88/cx88-vbi.c
    +++ b/drivers/media/pci/cx88/cx88-vbi.c
    @@ -144,11 +144,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 d3729be89252..b509c2a03852 100644
    --- a/drivers/media/pci/cx88/cx88-video.c
    +++ b/drivers/media/pci/cx88/cx88-video.c
    @@ -431,6 +431,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;
    @@ -445,35 +446,35 @@ 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,
    @@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
    buf, buf->vb.vb2_buf.index, __func__,
    core->width, core->height, dev->fmt->depth, dev->fmt->fourcc,
    (unsigned long)buf->risc.dma);
    - return 0;
    + return ret;
    }

    static void buffer_finish(struct vb2_buffer *vb)
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-10-19 12:38    [W:4.027 / U:0.136 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site