All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Anand Moon" <linux.amoon@gmail.com>
Cc: linux-amlogic@lists.infradead.org,
	dri-devel@lists.freedesktop.org, neil.armstrong@linaro.org
Subject: Re: [PATCH v7 03/19] media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread
Date: Mon, 13 Jul 2026 12:32:27 +0000	[thread overview]
Message-ID: <20260713123228.4172B1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260713120840.17427-4-linux.amoon@gmail.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

New issues:
- [Critical] vdec_close() frees session memory before releasing the V4L2 M2M context, triggering a NULL pointer dereference during queue teardown.
- [Critical] Unconditional execution of vdec_poweroff() and clearing of core->cur_sess in vdec_close() causes Data Abort panics and cross-session corruption.
- [Critical] Unconditional execution of vdec_poweroff() in vdec_close() leads to a double free of codec DMA allocations.
- [High] vdec_close() prematurely frees session context and DMA buffers without canceling background workqueues, causing Use-After-Free and DMA corruption.

Pre-existing issues:
- [High] Flawed logic in vdec_stop_streaming() orphans the recycle thread, leading to Use-After-Free during partial STREAMOFF.
- [Medium] The err_poweroff unwinding path in vdec_start_streaming() leaks sess->priv and associated codec assets.
--

--- Patch [3]: [PATCH v7 03/19] media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread ---
commit 41dac138c8515aa623b248b4a110d8a7802b604b
Author: Anand Moon <linux.amoon@gmail.com>
Subject: media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread

This patch validates the kthread_run return status during recycling thread
initialization to prevent memory leaks. It also ensures the thread is safely
stopped in both vdec_stop_streaming and vdec_close to prevent kernel panics
during teardown.

Closes: https://lore.kernel.org/all/20260521090944.F35401F00A3D@smtp.kernel.org/

diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
[ ... ]
@@ -353,13 +357,23 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
>  	schedule_work(&sess->esparser_queue_work);
>  	return 0;
>  
>  err_poweroff:
>  	vdec_poweroff(sess);
>  	vdec_free_canvas(sess);
>  	vdec_reset_timestamps(sess);
>  	vdec_reset_bufs_recycle(sess);

[Severity: Medium]
This is a pre-existing issue, but does the err_poweroff unwinding path leak
sess->priv?

If kthread_run() fails, execution jumps to the err_poweroff label which
unwinds various hardware states but misses calling kfree(sess->priv).
When the application retries VIDIOC_STREAMON, the codec's start routine
unconditionally allocates a new structure over sess->priv, permanently
stranding the previous allocation.

>  err_free_vififo:
>  	if (sess->vififo_vaddr) {
>  		dma_free_coherent(sess->core->dev, sess->vififo_size,
[ ... ]
@@ -464,7 +478,10 @@ static void vdec_stop_streaming(struct vb2_queue *q)
>  	if (full_cleanup) {
>  		if ((q->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
>  		     !sess->streamon_out) && vdec_codec_needs_recycle(sess)) {

[Severity: High]
This is a pre-existing issue, but does this logic orphan the recycle thread
leading to a use-after-free during partial STREAMOFF?

If userspace invokes VIDIOC_STREAMOFF exclusively on the capture queue
while the output queue remains active, this condition evaluates to false,
bypassing the kthread_stop() call.

Because old_status == STATUS_RUNNING, full_cleanup evaluates to true,
proceeding to dismantle the session context and free sess->priv.
The orphaned recycle thread may concurrently awaken and attempt to access
this freed memory.

> -			kthread_stop(sess->recycle_thread);
> +			if (!IS_ERR_OR_NULL(sess->recycle_thread)) {
> +				kthread_stop(sess->recycle_thread);
> +				sess->recycle_thread = NULL;
> +			}
>  		}
[ ... ]
@@ -970,6 +987,31 @@ static int vdec_open(struct file *file)
>  static int vdec_close(struct file *file)
>  {
>  	struct amvdec_session *sess = file_to_amvdec_session(file);
> +	struct amvdec_core *core = sess->core;
> +
> +	if (!IS_ERR_OR_NULL(sess->recycle_thread)) {
> +		kthread_stop(sess->recycle_thread);
> +		sess->recycle_thread = NULL;
> +	}
> +
> +	mutex_lock(&core->lock);
> +
> +	vdec_poweroff(sess);
> +	vdec_free_canvas(sess);
> +	core->cur_sess = NULL;

[Severity: Critical]
Can this unconditional invocation of vdec_poweroff() and clearing of
core->cur_sess cause Data Abort panics and cross-session corruption?

If userspace opens two instances (FDs), starts streaming on instance A
(acquiring hardware ownership), and then closes instance B:

vdec_close() for instance B will unconditionally call vdec_poweroff(sess)
and clear core->cur_sess, without verifying if instance B actually owns the
hardware.

This forces clock disablements while instance A is actively decoding. When
the hardware for instance A fires an interrupt, vdec_isr() will dereference
core->cur_sess, which was just wrongfully set to NULL, causing a panic.

[Severity: Critical]
Will this unconditional vdec_poweroff() call also lead to a double free of
codec DMA allocations?

If userspace cleanly shuts down streaming via VIDIOC_STREAMOFF,
vdec_stop_streaming() executes vdec_poweroff(). This invokes the codec
stop callback (like codec_h264_stop) which frees memory buffers but does
not set their pointers to NULL.

When userspace subsequently calls close(), vdec_close() calls
vdec_poweroff() again. The codec stop routine will execute a second time,
passing the same non-NULL pointers to dma_free_coherent() resulting in a
catastrophic double-free.

> +
> +	if (sess->vififo_vaddr) {
> +		dma_free_coherent(core->dev, sess->vififo_size,
> +				  sess->vififo_vaddr, sess->vififo_paddr);
> +		sess->vififo_vaddr = NULL;
> +		sess->vififo_paddr = 0;
> +	}
> +	vdec_reset_timestamps(sess);
> +	vdec_reset_bufs_recycle(sess);
> +	kfree(sess->priv);

[Severity: High]
Should we call cancel_work_sync(&sess->esparser_queue_work) before freeing
the session context and DMA buffers here?

If vdec_close() is called while the background workqueue is actively
processing frames, the DMA buffer (sess->vififo_vaddr) and session
structure (sess->priv) are immediately freed.

The concurrently executing workqueue continues its operation inside
esparser_queue(), dereferencing the freed sess->priv pointer and
instructing the hardware to perform DMA transfers into the freshly freed
physical address, potentially causing severe memory corruption.

> +	sess->priv = NULL;
> +
> +	mutex_unlock(&core->lock);
>  
>  	v4l2_m2m_ctx_release(sess->m2m_ctx);

[Severity: Critical]
Does this sequence trigger a NULL pointer dereference during queue teardown?

If a user closes the file descriptor without calling VIDIOC_STREAMOFF,
vdec_close() will free sess->priv and set it to NULL.

Immediately after, it calls v4l2_m2m_ctx_release(), which triggers
vdec_stop_streaming(). Since sess->status is still STATUS_RUNNING, the
driver will execute codec_ops->drain(sess).

The codec's drain function unconditionally dereferences sess->priv, which
was just set to NULL, causing an immediate panic.

>  	v4l2_fh_del(&sess->fh, file);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260713120840.17427-1-linux.amoon@gmail.com?part=3

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

WARNING: multiple messages have this Message-ID (diff)
From: sashiko-bot@kernel.org
To: "Anand Moon" <linux.amoon@gmail.com>
Cc: linux-amlogic@lists.infradead.org,
	dri-devel@lists.freedesktop.org, neil.armstrong@linaro.org
Subject: Re: [PATCH v7 03/19] media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread
Date: Mon, 13 Jul 2026 12:32:27 +0000	[thread overview]
Message-ID: <20260713123228.4172B1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260713120840.17427-4-linux.amoon@gmail.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

New issues:
- [Critical] vdec_close() frees session memory before releasing the V4L2 M2M context, triggering a NULL pointer dereference during queue teardown.
- [Critical] Unconditional execution of vdec_poweroff() and clearing of core->cur_sess in vdec_close() causes Data Abort panics and cross-session corruption.
- [Critical] Unconditional execution of vdec_poweroff() in vdec_close() leads to a double free of codec DMA allocations.
- [High] vdec_close() prematurely frees session context and DMA buffers without canceling background workqueues, causing Use-After-Free and DMA corruption.

Pre-existing issues:
- [High] Flawed logic in vdec_stop_streaming() orphans the recycle thread, leading to Use-After-Free during partial STREAMOFF.
- [Medium] The err_poweroff unwinding path in vdec_start_streaming() leaks sess->priv and associated codec assets.
--

--- Patch [3]: [PATCH v7 03/19] media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread ---
commit 41dac138c8515aa623b248b4a110d8a7802b604b
Author: Anand Moon <linux.amoon@gmail.com>
Subject: media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread

This patch validates the kthread_run return status during recycling thread
initialization to prevent memory leaks. It also ensures the thread is safely
stopped in both vdec_stop_streaming and vdec_close to prevent kernel panics
during teardown.

Closes: https://lore.kernel.org/all/20260521090944.F35401F00A3D@smtp.kernel.org/

diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
[ ... ]
@@ -353,13 +357,23 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
>  	schedule_work(&sess->esparser_queue_work);
>  	return 0;
>  
>  err_poweroff:
>  	vdec_poweroff(sess);
>  	vdec_free_canvas(sess);
>  	vdec_reset_timestamps(sess);
>  	vdec_reset_bufs_recycle(sess);

[Severity: Medium]
This is a pre-existing issue, but does the err_poweroff unwinding path leak
sess->priv?

If kthread_run() fails, execution jumps to the err_poweroff label which
unwinds various hardware states but misses calling kfree(sess->priv).
When the application retries VIDIOC_STREAMON, the codec's start routine
unconditionally allocates a new structure over sess->priv, permanently
stranding the previous allocation.

>  err_free_vififo:
>  	if (sess->vififo_vaddr) {
>  		dma_free_coherent(sess->core->dev, sess->vififo_size,
[ ... ]
@@ -464,7 +478,10 @@ static void vdec_stop_streaming(struct vb2_queue *q)
>  	if (full_cleanup) {
>  		if ((q->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
>  		     !sess->streamon_out) && vdec_codec_needs_recycle(sess)) {

[Severity: High]
This is a pre-existing issue, but does this logic orphan the recycle thread
leading to a use-after-free during partial STREAMOFF?

If userspace invokes VIDIOC_STREAMOFF exclusively on the capture queue
while the output queue remains active, this condition evaluates to false,
bypassing the kthread_stop() call.

Because old_status == STATUS_RUNNING, full_cleanup evaluates to true,
proceeding to dismantle the session context and free sess->priv.
The orphaned recycle thread may concurrently awaken and attempt to access
this freed memory.

> -			kthread_stop(sess->recycle_thread);
> +			if (!IS_ERR_OR_NULL(sess->recycle_thread)) {
> +				kthread_stop(sess->recycle_thread);
> +				sess->recycle_thread = NULL;
> +			}
>  		}
[ ... ]
@@ -970,6 +987,31 @@ static int vdec_open(struct file *file)
>  static int vdec_close(struct file *file)
>  {
>  	struct amvdec_session *sess = file_to_amvdec_session(file);
> +	struct amvdec_core *core = sess->core;
> +
> +	if (!IS_ERR_OR_NULL(sess->recycle_thread)) {
> +		kthread_stop(sess->recycle_thread);
> +		sess->recycle_thread = NULL;
> +	}
> +
> +	mutex_lock(&core->lock);
> +
> +	vdec_poweroff(sess);
> +	vdec_free_canvas(sess);
> +	core->cur_sess = NULL;

[Severity: Critical]
Can this unconditional invocation of vdec_poweroff() and clearing of
core->cur_sess cause Data Abort panics and cross-session corruption?

If userspace opens two instances (FDs), starts streaming on instance A
(acquiring hardware ownership), and then closes instance B:

vdec_close() for instance B will unconditionally call vdec_poweroff(sess)
and clear core->cur_sess, without verifying if instance B actually owns the
hardware.

This forces clock disablements while instance A is actively decoding. When
the hardware for instance A fires an interrupt, vdec_isr() will dereference
core->cur_sess, which was just wrongfully set to NULL, causing a panic.

[Severity: Critical]
Will this unconditional vdec_poweroff() call also lead to a double free of
codec DMA allocations?

If userspace cleanly shuts down streaming via VIDIOC_STREAMOFF,
vdec_stop_streaming() executes vdec_poweroff(). This invokes the codec
stop callback (like codec_h264_stop) which frees memory buffers but does
not set their pointers to NULL.

When userspace subsequently calls close(), vdec_close() calls
vdec_poweroff() again. The codec stop routine will execute a second time,
passing the same non-NULL pointers to dma_free_coherent() resulting in a
catastrophic double-free.

> +
> +	if (sess->vififo_vaddr) {
> +		dma_free_coherent(core->dev, sess->vififo_size,
> +				  sess->vififo_vaddr, sess->vififo_paddr);
> +		sess->vififo_vaddr = NULL;
> +		sess->vififo_paddr = 0;
> +	}
> +	vdec_reset_timestamps(sess);
> +	vdec_reset_bufs_recycle(sess);
> +	kfree(sess->priv);

[Severity: High]
Should we call cancel_work_sync(&sess->esparser_queue_work) before freeing
the session context and DMA buffers here?

If vdec_close() is called while the background workqueue is actively
processing frames, the DMA buffer (sess->vififo_vaddr) and session
structure (sess->priv) are immediately freed.

The concurrently executing workqueue continues its operation inside
esparser_queue(), dereferencing the freed sess->priv pointer and
instructing the hardware to perform DMA transfers into the freshly freed
physical address, potentially causing severe memory corruption.

> +	sess->priv = NULL;
> +
> +	mutex_unlock(&core->lock);
>  
>  	v4l2_m2m_ctx_release(sess->m2m_ctx);

[Severity: Critical]
Does this sequence trigger a NULL pointer dereference during queue teardown?

If a user closes the file descriptor without calling VIDIOC_STREAMOFF,
vdec_close() will free sess->priv and set it to NULL.

Immediately after, it calls v4l2_m2m_ctx_release(), which triggers
vdec_stop_streaming(). Since sess->status is still STATUS_RUNNING, the
driver will execute codec_ops->drain(sess).

The codec's drain function unconditionally dereferences sess->priv, which
was just set to NULL, causing an immediate panic.

>  	v4l2_fh_del(&sess->fh, file);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260713120840.17427-1-linux.amoon@gmail.com?part=3

  reply	other threads:[~2026-07-13 12:32 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-13 12:06 [PATCH v7 00/19] media: meson: vdec: Fix lifecycles, race conditions, and stability bugs Anand Moon
2026-07-13 12:06 ` Anand Moon
2026-07-13 12:06 ` Anand Moon
2026-07-13 12:06 ` [PATCH v7 01/19] media: meson: vdec: Fix m2m device lifetime and cleanup path Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:35   ` sashiko-bot
2026-07-13 12:35     ` sashiko-bot
2026-07-13 12:06 ` [PATCH v7 02/19] media: meson: vdec: Fix STREAMON / STREAMOFF race conditions and session teardown Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:38   ` sashiko-bot
2026-07-13 12:38     ` sashiko-bot
2026-07-13 12:06 ` [PATCH v7 03/19] media: meson: vdec: Fix lifecycle leaks and race conditions in recycle_thread Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:32   ` sashiko-bot [this message]
2026-07-13 12:32     ` sashiko-bot
2026-07-13 12:06 ` [PATCH v7 04/19] media: meson: vdec: Fix use-after-free race between teardown and ISR routines Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:06   ` Anand Moon
2026-07-13 12:23   ` sashiko-bot
2026-07-13 12:23     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 05/19] media: meson: vdec: Fix race condition and synchronize esparser IRQ Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:28   ` sashiko-bot
2026-07-13 12:28     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 06/19] media: meson: vdec: Fix race condition by canceling work sync Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:33   ` sashiko-bot
2026-07-13 12:33     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 07/19] media: meson: vdec: Refactor esparser work queue and fix teardown race Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:27   ` sashiko-bot
2026-07-13 12:27     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 08/19] media: meson: vdec: Fix concurrent execution races and unsafe teardown Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:42   ` sashiko-bot
2026-07-13 12:42     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 09/19] media: meson: vdec: Fix vp9 header update failure on invalid payloads Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:42   ` sashiko-bot
2026-07-13 12:42     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 10/19] media: meson: vdec: Fix race conditions and leaks in esparser pipeline Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:46   ` sashiko-bot
2026-07-13 12:46     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 11/19] media: meson: vdec: Update core m2m stream state during transitions Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:48   ` sashiko-bot
2026-07-13 12:48     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 12/19] media: meson: vdec: Coordinate m2m task execution inside async loop Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:54   ` sashiko-bot
2026-07-13 12:54     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 13/19] media: meson: vdec: Fix race conditions in job abort sequence Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:55   ` sashiko-bot
2026-07-13 12:55     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 14/19] media: meson: vdec: Correct atomic counter placement in dst_buf_done Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:48   ` sashiko-bot
2026-07-13 12:48     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 15/19] media: meson: vdec: Fix concurrent firmware loading race and hardware timeout Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:56   ` sashiko-bot
2026-07-13 12:56     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 16/19] media: meson: vdec: Configure DMA mask and segment size in probe Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:55   ` sashiko-bot
2026-07-13 12:55     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 17/19] media: meson: canvas: Fix Use-After-Free by linking canvas provider device Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:58   ` sashiko-bot
2026-07-13 12:58     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 18/19] media: meson: vdec: Increase VIFIFO buffer size to 32 MiB Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 13:06   ` sashiko-bot
2026-07-13 13:06     ` sashiko-bot
2026-07-13 12:07 ` [PATCH v7 19/19] gpu: drm: meson: Fix DMA segment size limits and maximize allocation boundaries Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:07   ` Anand Moon
2026-07-13 12:57   ` sashiko-bot
2026-07-13 12:57     ` sashiko-bot
2026-07-13 14:04   ` Nicolas Dufresne
2026-07-13 14:04     ` Nicolas Dufresne
2026-07-14  7:23 ` [PATCH v7 00/19] media: meson: vdec: Fix lifecycles, race conditions, and stability bugs Anand Moon
2026-07-14  7:23   ` Anand Moon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260713123228.4172B1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux.amoon@gmail.com \
    --cc=neil.armstrong@linaro.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.