From 0f9b8ed569cf862cc2d7941428aa7a0707f1ed60 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: May 25 2023 06:19:12 +0000 Subject: media: cx23885: Fix a null-ptr-deref bug in buffer_prepare() and buffer_finish() (git-fixes). --- diff --git a/patches.suse/media-cx23885-Fix-a-null-ptr-deref-bug-in-buffer_pre.patch b/patches.suse/media-cx23885-Fix-a-null-ptr-deref-bug-in-buffer_pre.patch new file mode 100644 index 0000000..7ab994a --- /dev/null +++ b/patches.suse/media-cx23885-Fix-a-null-ptr-deref-bug-in-buffer_pre.patch @@ -0,0 +1,109 @@ +From 47e8b73bc35d7c54642f78e498697692f6358996 Mon Sep 17 00:00:00 2001 +From: harperchen +Date: Thu, 2 Mar 2023 13:39:05 +0100 +Subject: [PATCH] media: cx23885: Fix a null-ptr-deref bug in buffer_prepare() and buffer_finish() +Git-commit: 47e8b73bc35d7c54642f78e498697692f6358996 +Patch-mainline: v6.4-rc1 +References: git-fixes + +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 +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/pci/cx23885/cx23885-core.c | 4 +++- + drivers/media/pci/cx23885/cx23885-video.c | 13 +++++++------ + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c +index 9232a966bcab..2ce2914576cf 100644 +--- a/drivers/media/pci/cx23885/cx23885-core.c ++++ b/drivers/media/pci/cx23885/cx23885-core.c +@@ -1325,7 +1325,9 @@ void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf) + { + struct cx23885_riscmem *risc = &buf->risc; + +- dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma); ++ if (risc->cpu) ++ dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma); ++ memset(risc, 0, sizeof(*risc)); + } + + static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) +diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c +index 3d03f5e95786..671fc0588e43 100644 +--- a/drivers/media/pci/cx23885/cx23885-video.c ++++ b/drivers/media/pci/cx23885/cx23885-video.c +@@ -342,6 +342,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 cx23885_dev *dev = vb->vb2_queue->drv_priv; + struct cx23885_buffer *buf = +@@ -358,12 +359,12 @@ static int buffer_prepare(struct vb2_buffer *vb) + + switch (dev->field) { + case V4L2_FIELD_TOP: +- cx23885_risc_buffer(dev->pci, &buf->risc, ++ ret = cx23885_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, 0, UNSET, + buf->bpl, 0, dev->height); + break; + case V4L2_FIELD_BOTTOM: +- cx23885_risc_buffer(dev->pci, &buf->risc, ++ ret = cx23885_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, UNSET, 0, + buf->bpl, 0, dev->height); + break; +@@ -391,21 +392,21 @@ static int buffer_prepare(struct vb2_buffer *vb) + line0_offset = 0; + line1_offset = buf->bpl; + } +- cx23885_risc_buffer(dev->pci, &buf->risc, ++ ret = cx23885_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, line0_offset, + line1_offset, + buf->bpl, buf->bpl, + dev->height >> 1); + break; + case V4L2_FIELD_SEQ_TB: +- cx23885_risc_buffer(dev->pci, &buf->risc, ++ ret = cx23885_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, + 0, buf->bpl * (dev->height >> 1), + buf->bpl, 0, + dev->height >> 1); + break; + case V4L2_FIELD_SEQ_BT: +- cx23885_risc_buffer(dev->pci, &buf->risc, ++ ret = cx23885_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, + buf->bpl * (dev->height >> 1), 0, + buf->bpl, 0, +@@ -418,7 +419,7 @@ static int buffer_prepare(struct vb2_buffer *vb) + buf, buf->vb.vb2_buf.index, + dev->width, dev->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.3 + diff --git a/series.conf b/series.conf index 44791f8..14d8e54 100644 --- a/series.conf +++ b/series.conf @@ -19844,6 +19844,7 @@ patches.suse/drm-amd-Fix-an-out-of-bounds-error-in-BIOS-parser.patch patches.suse/drm-amd-display-Fix-potential-null-dereference.patch patches.suse/drm-i915-Make-intel_get_crtc_new_encoder-less-oopsy.patch + patches.suse/media-cx23885-Fix-a-null-ptr-deref-bug-in-buffer_pre.patch patches.suse/media-av7110-prevent-underflow-in-write_ts_to_decode.patch patches.suse/media-max9286-Free-control-handler.patch patches.suse/media-rkvdec-fix-use-after-free-bug-in-rkvdec_remove.patch