Commit 2b064d91 authored by Zheyu Ma's avatar Zheyu Ma Committed by Mauro Carvalho Chehab

media: cx88: Fix a null-ptr-deref bug in buffer_prepare()

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: default avatarZheyu Ma <zheyuma97@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 211f8304
...@@ -144,11 +144,10 @@ static int buffer_prepare(struct vb2_buffer *vb) ...@@ -144,11 +144,10 @@ static int buffer_prepare(struct vb2_buffer *vb)
return -EINVAL; return -EINVAL;
vb2_set_plane_payload(vb, 0, size); vb2_set_plane_payload(vb, 0, size);
cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
0, VBI_LINE_LENGTH * lines, 0, VBI_LINE_LENGTH * lines,
VBI_LINE_LENGTH, 0, VBI_LINE_LENGTH, 0,
lines); lines);
return 0;
} }
static void buffer_finish(struct vb2_buffer *vb) static void buffer_finish(struct vb2_buffer *vb)
......
...@@ -431,6 +431,7 @@ static int queue_setup(struct vb2_queue *q, ...@@ -431,6 +431,7 @@ static int queue_setup(struct vb2_queue *q,
static int buffer_prepare(struct vb2_buffer *vb) static int buffer_prepare(struct vb2_buffer *vb)
{ {
int ret;
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
struct cx88_core *core = dev->core; struct cx88_core *core = dev->core;
...@@ -445,35 +446,35 @@ static int buffer_prepare(struct vb2_buffer *vb) ...@@ -445,35 +446,35 @@ static int buffer_prepare(struct vb2_buffer *vb)
switch (core->field) { switch (core->field) {
case V4L2_FIELD_TOP: case V4L2_FIELD_TOP:
cx88_risc_buffer(dev->pci, &buf->risc, ret = cx88_risc_buffer(dev->pci, &buf->risc,
sgt->sgl, 0, UNSET, sgt->sgl, 0, UNSET,
buf->bpl, 0, core->height); buf->bpl, 0, core->height);
break; break;
case V4L2_FIELD_BOTTOM: case V4L2_FIELD_BOTTOM:
cx88_risc_buffer(dev->pci, &buf->risc, ret = cx88_risc_buffer(dev->pci, &buf->risc,
sgt->sgl, UNSET, 0, sgt->sgl, UNSET, 0,
buf->bpl, 0, core->height); buf->bpl, 0, core->height);
break; break;
case V4L2_FIELD_SEQ_TB: case V4L2_FIELD_SEQ_TB:
cx88_risc_buffer(dev->pci, &buf->risc, ret = cx88_risc_buffer(dev->pci, &buf->risc,
sgt->sgl, sgt->sgl,
0, buf->bpl * (core->height >> 1), 0, buf->bpl * (core->height >> 1),
buf->bpl, 0, buf->bpl, 0,
core->height >> 1); core->height >> 1);
break; break;
case V4L2_FIELD_SEQ_BT: case V4L2_FIELD_SEQ_BT:
cx88_risc_buffer(dev->pci, &buf->risc, ret = cx88_risc_buffer(dev->pci, &buf->risc,
sgt->sgl, sgt->sgl,
buf->bpl * (core->height >> 1), 0, buf->bpl * (core->height >> 1), 0,
buf->bpl, 0, buf->bpl, 0,
core->height >> 1); core->height >> 1);
break; break;
case V4L2_FIELD_INTERLACED: case V4L2_FIELD_INTERLACED:
default: default:
cx88_risc_buffer(dev->pci, &buf->risc, ret = cx88_risc_buffer(dev->pci, &buf->risc,
sgt->sgl, 0, buf->bpl, sgt->sgl, 0, buf->bpl,
buf->bpl, buf->bpl, buf->bpl, buf->bpl,
core->height >> 1); core->height >> 1);
break; break;
} }
dprintk(2, dprintk(2,
...@@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb) ...@@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
buf, buf->vb.vb2_buf.index, __func__, buf, buf->vb.vb2_buf.index, __func__,
core->width, core->height, dev->fmt->depth, dev->fmt->fourcc, core->width, core->height, dev->fmt->depth, dev->fmt->fourcc,
(unsigned long)buf->risc.dma); (unsigned long)buf->risc.dma);
return 0; return ret;
} }
static void buffer_finish(struct vb2_buffer *vb) static void buffer_finish(struct vb2_buffer *vb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment