mirror of
https://github.com/torvalds/linux.git
synced 2026-06-06 13:37:36 +02:00
media: cx88: Fix a null-ptr-deref bug in buffer_prepare()
[ Upstream commit 2b064d9144 ]
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>
This commit is contained in:
parent
d9e2585c3b
commit
c2257c8a50
|
|
@ -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,
|
||||||
|
|
||||||
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,24 +446,24 @@ 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,
|
||||||
|
|
@ -470,7 +471,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
||||||
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);
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user