Skip to content

Commit b6b3432

Browse files
harperchensmb49
authored andcommitted
media: cx23885: Fix a null-ptr-deref bug in buffer_prepare() and buffer_finish()
BugLink: https://bugs.launchpad.net/bugs/2028808 [ Upstream commit 47e8b73 ] When the driver calls cx23885_risc_buffer() to prepare the buffer, the function call dma_alloc_coherent may fail, resulting in a empty buffer risc->cpu. Later when we free the buffer or access the buffer, null ptr deref is triggered. This bug is similar to the following one: https://git.linuxtv.org/media_stage.git/commit/?id=2b064d91440b33fba5b452f2d1b31f13ae911d71. We believe the bug can be also dynamically triggered from user side. Similarly, we fix this by checking the return value of cx23885_risc_buffer() and the value of risc->cpu before buffer free. Signed-off-by: harperchen <harperchen1110@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> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent 07ff254 commit b6b3432

2 files changed

Lines changed: 10 additions & 7 deletions

File tree

drivers/media/pci/cx23885/cx23885-core.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,9 @@ void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
13251325
{
13261326
struct cx23885_riscmem *risc = &buf->risc;
13271327

1328-
dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma);
1328+
if (risc->cpu)
1329+
dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma);
1330+
memset(risc, 0, sizeof(*risc));
13291331
}
13301332

13311333
static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)

drivers/media/pci/cx23885/cx23885-video.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ static int queue_setup(struct vb2_queue *q,
342342

343343
static int buffer_prepare(struct vb2_buffer *vb)
344344
{
345+
int ret;
345346
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
346347
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
347348
struct cx23885_buffer *buf =
@@ -358,12 +359,12 @@ static int buffer_prepare(struct vb2_buffer *vb)
358359

359360
switch (dev->field) {
360361
case V4L2_FIELD_TOP:
361-
cx23885_risc_buffer(dev->pci, &buf->risc,
362+
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
362363
sgt->sgl, 0, UNSET,
363364
buf->bpl, 0, dev->height);
364365
break;
365366
case V4L2_FIELD_BOTTOM:
366-
cx23885_risc_buffer(dev->pci, &buf->risc,
367+
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
367368
sgt->sgl, UNSET, 0,
368369
buf->bpl, 0, dev->height);
369370
break;
@@ -391,21 +392,21 @@ static int buffer_prepare(struct vb2_buffer *vb)
391392
line0_offset = 0;
392393
line1_offset = buf->bpl;
393394
}
394-
cx23885_risc_buffer(dev->pci, &buf->risc,
395+
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
395396
sgt->sgl, line0_offset,
396397
line1_offset,
397398
buf->bpl, buf->bpl,
398399
dev->height >> 1);
399400
break;
400401
case V4L2_FIELD_SEQ_TB:
401-
cx23885_risc_buffer(dev->pci, &buf->risc,
402+
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
402403
sgt->sgl,
403404
0, buf->bpl * (dev->height >> 1),
404405
buf->bpl, 0,
405406
dev->height >> 1);
406407
break;
407408
case V4L2_FIELD_SEQ_BT:
408-
cx23885_risc_buffer(dev->pci, &buf->risc,
409+
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
409410
sgt->sgl,
410411
buf->bpl * (dev->height >> 1), 0,
411412
buf->bpl, 0,
@@ -418,7 +419,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
418419
buf, buf->vb.vb2_buf.index,
419420
dev->width, dev->height, dev->fmt->depth, dev->fmt->fourcc,
420421
(unsigned long)buf->risc.dma);
421-
return 0;
422+
return ret;
422423
}
423424

424425
static void buffer_finish(struct vb2_buffer *vb)

0 commit comments

Comments
 (0)