]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: amphion: Fix race between m2m job_abort and device_run
authorMing Qian <ming.qian@oss.nxp.com>
Fri, 6 Mar 2026 06:59:50 +0000 (14:59 +0800)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Mon, 23 Mar 2026 10:18:34 +0000 (11:18 +0100)
Fix kernel panic caused by race condition where v4l2_m2m_ctx_release()
frees m2m_ctx while v4l2_m2m_try_run() is about to call device_run
with the same context.

Race sequence:
  v4l2_m2m_try_run():           v4l2_m2m_ctx_release():
    lock/unlock                   v4l2_m2m_cancel_job()
                                    job_abort()
                                      v4l2_m2m_job_finish()
                                  kfree(m2m_ctx)  <- frees ctx
    device_run()  <- use-after-free crash at 0x538

Crash trace:
  Unable to handle kernel read from unreadable memory at virtual address
  0000000000000538
  v4l2_m2m_try_run+0x78/0x138
  v4l2_m2m_device_run_work+0x14/0x20

The amphion vpu driver does not rely on the m2m framework's device_run
callback to perform encode/decode operations.

Fix the race by preventing m2m framework job scheduling entirely:
- Add job_ready callback returning 0 (no jobs ready for m2m framework)
- Remove job_abort callback to avoid the race condition

Fixes: 3cd084519c6f ("media: amphion: add vpu v4l2 m2m support")
Cc: stable@vger.kernel.org
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/amphion/vpu_v4l2.c

index 64fc88d89cccdc80e2e5e0c687f1914c14ad9cce..7cccc994fc5029e7db2e7fa20dfa6e608aee6a34 100644 (file)
@@ -447,17 +447,14 @@ static void vpu_m2m_device_run(void *priv)
 {
 }
 
-static void vpu_m2m_job_abort(void *priv)
+static int vpu_m2m_job_ready(void *priv)
 {
-       struct vpu_inst *inst = priv;
-       struct v4l2_m2m_ctx *m2m_ctx = inst->fh.m2m_ctx;
-
-       v4l2_m2m_job_finish(m2m_ctx->m2m_dev, m2m_ctx);
+       return 0;
 }
 
 static const struct v4l2_m2m_ops vpu_m2m_ops = {
        .device_run = vpu_m2m_device_run,
-       .job_abort = vpu_m2m_job_abort
+       .job_ready = vpu_m2m_job_ready,
 };
 
 static int vpu_vb2_queue_setup(struct vb2_queue *vq,