CVE-2026-31584 (GCVE-0-2026-31584)
Vulnerability from cvelistv5 – Published: 2026-04-24 14:42 – Updated: 2026-04-24 14:42
VLAI?
Title
media: mediatek: vcodec: fix use-after-free in encoder release path
Summary
In the Linux kernel, the following vulnerability has been resolved:
media: mediatek: vcodec: fix use-after-free in encoder release path
The fops_vcodec_release() function frees the context structure (ctx)
without first cancelling any pending or running work in ctx->encode_work.
This creates a race window where the workqueue handler (mtk_venc_worker)
may still be accessing the context memory after it has been freed.
Race condition:
CPU 0 (release path) CPU 1 (workqueue)
--------------------- ------------------
fops_vcodec_release()
v4l2_m2m_ctx_release()
v4l2_m2m_cancel_job()
// waits for m2m job "done"
mtk_venc_worker()
v4l2_m2m_job_finish()
// m2m job "done"
// BUT worker still running!
// post-job_finish access:
other ctx dereferences
// UAF if ctx already freed
// returns (job "done")
kfree(ctx) // ctx freed
Root cause: The v4l2_m2m_ctx_release() only waits for the m2m job
lifecycle (via TRANS_RUNNING flag), not the workqueue lifecycle.
After v4l2_m2m_job_finish() is called, the m2m framework considers
the job complete and v4l2_m2m_ctx_release() returns, but the worker
function continues executing and may still access ctx.
The work is queued during encode operations via:
queue_work(ctx->dev->encode_workqueue, &ctx->encode_work)
The worker function accesses ctx->m2m_ctx, ctx->dev, and other ctx
fields even after calling v4l2_m2m_job_finish().
This vulnerability was confirmed with KASAN by running an instrumented
test module that widens the post-job_finish race window. KASAN detected:
BUG: KASAN: slab-use-after-free in mtk_venc_worker+0x159/0x180
Read of size 4 at addr ffff88800326e000 by task kworker/u8:0/12
Workqueue: mtk_vcodec_enc_wq mtk_venc_worker
Allocated by task 47:
__kasan_kmalloc+0x7f/0x90
fops_vcodec_open+0x85/0x1a0
Freed by task 47:
__kasan_slab_free+0x43/0x70
kfree+0xee/0x3a0
fops_vcodec_release+0xb7/0x190
Fix this by calling cancel_work_sync(&ctx->encode_work) before kfree(ctx).
This ensures the workqueue handler is both cancelled (if pending) and
synchronized (waits for any running handler to complete) before the
context is freed.
Placement rationale: The fix is placed after v4l2_ctrl_handler_free()
and before list_del_init(&ctx->list). At this point, all m2m operations
are done (v4l2_m2m_ctx_release() has returned), and we need to ensure
the workqueue is synchronized before removing ctx from the list and
freeing it.
Note: The open error path does NOT need cancel_work_sync() because
INIT_WORK() only initializes the work structure - it does not schedule
it. Work is only scheduled later during device_run() operations.
Severity ?
No CVSS data available.
Assigner
References
Impacted products
| Vendor | Product | Version | ||
|---|---|---|---|---|
| Linux | Linux |
Affected:
1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 , < a8a55913552aed45108525d1851c65e1db0cc25b
(git)
Affected: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 , < f99353cd0e9f58bf17889049137b8d65fb44ebf1 (git) Affected: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 , < 93d9a58961a9e09306857e999b3ee76aa4be67f0 (git) Affected: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 , < f1692337c6fa26e04f89b22a4d84bf5b7ada50d1 (git) |
||
{
"containers": {
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "a8a55913552aed45108525d1851c65e1db0cc25b",
"status": "affected",
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"versionType": "git"
},
{
"lessThan": "f99353cd0e9f58bf17889049137b8d65fb44ebf1",
"status": "affected",
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"versionType": "git"
},
{
"lessThan": "93d9a58961a9e09306857e999b3ee76aa4be67f0",
"status": "affected",
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"versionType": "git"
},
{
"lessThan": "f1692337c6fa26e04f89b22a4d84bf5b7ada50d1",
"status": "affected",
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThanOrEqual": "6.12.*",
"status": "unaffected",
"version": "6.12.83",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.18.*",
"status": "unaffected",
"version": "6.18.24",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.19.*",
"status": "unaffected",
"version": "6.19.14",
"versionType": "semver"
},
{
"lessThanOrEqual": "7.0.*",
"status": "unaffected",
"version": "7.0.1",
"versionType": "semver"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.12.83",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.18.24",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.19.14",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "7.0.1",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nmedia: mediatek: vcodec: fix use-after-free in encoder release path\n\nThe fops_vcodec_release() function frees the context structure (ctx)\nwithout first cancelling any pending or running work in ctx-\u003eencode_work.\nThis creates a race window where the workqueue handler (mtk_venc_worker)\nmay still be accessing the context memory after it has been freed.\n\nRace condition:\n\n CPU 0 (release path) CPU 1 (workqueue)\n --------------------- ------------------\n fops_vcodec_release()\n v4l2_m2m_ctx_release()\n v4l2_m2m_cancel_job()\n // waits for m2m job \"done\"\n mtk_venc_worker()\n v4l2_m2m_job_finish()\n // m2m job \"done\"\n // BUT worker still running!\n // post-job_finish access:\n other ctx dereferences\n // UAF if ctx already freed\n // returns (job \"done\")\n kfree(ctx) // ctx freed\n\nRoot cause: The v4l2_m2m_ctx_release() only waits for the m2m job\nlifecycle (via TRANS_RUNNING flag), not the workqueue lifecycle.\nAfter v4l2_m2m_job_finish() is called, the m2m framework considers\nthe job complete and v4l2_m2m_ctx_release() returns, but the worker\nfunction continues executing and may still access ctx.\n\nThe work is queued during encode operations via:\n queue_work(ctx-\u003edev-\u003eencode_workqueue, \u0026ctx-\u003eencode_work)\nThe worker function accesses ctx-\u003em2m_ctx, ctx-\u003edev, and other ctx\nfields even after calling v4l2_m2m_job_finish().\n\nThis vulnerability was confirmed with KASAN by running an instrumented\ntest module that widens the post-job_finish race window. KASAN detected:\n\n BUG: KASAN: slab-use-after-free in mtk_venc_worker+0x159/0x180\n Read of size 4 at addr ffff88800326e000 by task kworker/u8:0/12\n\n Workqueue: mtk_vcodec_enc_wq mtk_venc_worker\n\n Allocated by task 47:\n __kasan_kmalloc+0x7f/0x90\n fops_vcodec_open+0x85/0x1a0\n\n Freed by task 47:\n __kasan_slab_free+0x43/0x70\n kfree+0xee/0x3a0\n fops_vcodec_release+0xb7/0x190\n\nFix this by calling cancel_work_sync(\u0026ctx-\u003eencode_work) before kfree(ctx).\nThis ensures the workqueue handler is both cancelled (if pending) and\nsynchronized (waits for any running handler to complete) before the\ncontext is freed.\n\nPlacement rationale: The fix is placed after v4l2_ctrl_handler_free()\nand before list_del_init(\u0026ctx-\u003elist). At this point, all m2m operations\nare done (v4l2_m2m_ctx_release() has returned), and we need to ensure\nthe workqueue is synchronized before removing ctx from the list and\nfreeing it.\n\nNote: The open error path does NOT need cancel_work_sync() because\nINIT_WORK() only initializes the work structure - it does not schedule\nit. Work is only scheduled later during device_run() operations."
}
],
"providerMetadata": {
"dateUpdated": "2026-04-24T14:42:13.586Z",
"orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"shortName": "Linux"
},
"references": [
{
"url": "https://git.kernel.org/stable/c/a8a55913552aed45108525d1851c65e1db0cc25b"
},
{
"url": "https://git.kernel.org/stable/c/f99353cd0e9f58bf17889049137b8d65fb44ebf1"
},
{
"url": "https://git.kernel.org/stable/c/93d9a58961a9e09306857e999b3ee76aa4be67f0"
},
{
"url": "https://git.kernel.org/stable/c/f1692337c6fa26e04f89b22a4d84bf5b7ada50d1"
}
],
"title": "media: mediatek: vcodec: fix use-after-free in encoder release path",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"assignerShortName": "Linux",
"cveId": "CVE-2026-31584",
"datePublished": "2026-04-24T14:42:13.586Z",
"dateReserved": "2026-03-09T15:48:24.120Z",
"dateUpdated": "2026-04-24T14:42:13.586Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"epss": {
"cve": "CVE-2026-31584",
"date": "2026-04-25",
"epss": "0.00018",
"percentile": "0.04621"
},
"nvd": "{\"cve\":{\"id\":\"CVE-2026-31584\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2026-04-24T15:16:33.117\",\"lastModified\":\"2026-04-24T17:51:40.810\",\"vulnStatus\":\"Awaiting Analysis\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nmedia: mediatek: vcodec: fix use-after-free in encoder release path\\n\\nThe fops_vcodec_release() function frees the context structure (ctx)\\nwithout first cancelling any pending or running work in ctx-\u003eencode_work.\\nThis creates a race window where the workqueue handler (mtk_venc_worker)\\nmay still be accessing the context memory after it has been freed.\\n\\nRace condition:\\n\\n CPU 0 (release path) CPU 1 (workqueue)\\n --------------------- ------------------\\n fops_vcodec_release()\\n v4l2_m2m_ctx_release()\\n v4l2_m2m_cancel_job()\\n // waits for m2m job \\\"done\\\"\\n mtk_venc_worker()\\n v4l2_m2m_job_finish()\\n // m2m job \\\"done\\\"\\n // BUT worker still running!\\n // post-job_finish access:\\n other ctx dereferences\\n // UAF if ctx already freed\\n // returns (job \\\"done\\\")\\n kfree(ctx) // ctx freed\\n\\nRoot cause: The v4l2_m2m_ctx_release() only waits for the m2m job\\nlifecycle (via TRANS_RUNNING flag), not the workqueue lifecycle.\\nAfter v4l2_m2m_job_finish() is called, the m2m framework considers\\nthe job complete and v4l2_m2m_ctx_release() returns, but the worker\\nfunction continues executing and may still access ctx.\\n\\nThe work is queued during encode operations via:\\n queue_work(ctx-\u003edev-\u003eencode_workqueue, \u0026ctx-\u003eencode_work)\\nThe worker function accesses ctx-\u003em2m_ctx, ctx-\u003edev, and other ctx\\nfields even after calling v4l2_m2m_job_finish().\\n\\nThis vulnerability was confirmed with KASAN by running an instrumented\\ntest module that widens the post-job_finish race window. KASAN detected:\\n\\n BUG: KASAN: slab-use-after-free in mtk_venc_worker+0x159/0x180\\n Read of size 4 at addr ffff88800326e000 by task kworker/u8:0/12\\n\\n Workqueue: mtk_vcodec_enc_wq mtk_venc_worker\\n\\n Allocated by task 47:\\n __kasan_kmalloc+0x7f/0x90\\n fops_vcodec_open+0x85/0x1a0\\n\\n Freed by task 47:\\n __kasan_slab_free+0x43/0x70\\n kfree+0xee/0x3a0\\n fops_vcodec_release+0xb7/0x190\\n\\nFix this by calling cancel_work_sync(\u0026ctx-\u003eencode_work) before kfree(ctx).\\nThis ensures the workqueue handler is both cancelled (if pending) and\\nsynchronized (waits for any running handler to complete) before the\\ncontext is freed.\\n\\nPlacement rationale: The fix is placed after v4l2_ctrl_handler_free()\\nand before list_del_init(\u0026ctx-\u003elist). At this point, all m2m operations\\nare done (v4l2_m2m_ctx_release() has returned), and we need to ensure\\nthe workqueue is synchronized before removing ctx from the list and\\nfreeing it.\\n\\nNote: The open error path does NOT need cancel_work_sync() because\\nINIT_WORK() only initializes the work structure - it does not schedule\\nit. Work is only scheduled later during device_run() operations.\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/93d9a58961a9e09306857e999b3ee76aa4be67f0\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/a8a55913552aed45108525d1851c65e1db0cc25b\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/f1692337c6fa26e04f89b22a4d84bf5b7ada50d1\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/f99353cd0e9f58bf17889049137b8d65fb44ebf1\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}"
}
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…