{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2024-56552", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2024-12-27T14:03:05.990Z", "datePublished": "2024-12-27T14:22:54.140Z", "dateUpdated": "2026-08-05T11:45:00.626Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T11:45:00.626Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\ndrm/xe/guc_submit: fix race around suspend_pending\n\nCurrently in some testcases we can trigger:\n\nxe 0000:03:00.0: [drm] Assertion `exec_queue_destroyed(q)` failed!\n....\nWARNING: CPU: 18 PID: 2640 at drivers/gpu/drm/xe/xe_guc_submit.c:1826 xe_guc_sched_done_handler+0xa54/0xef0 [xe]\nxe 0000:03:00.0: [drm] *ERROR* GT1: DEREGISTER_DONE: Unexpected engine state 0x00a1, guc_id=57\n\nLooking at a snippet of corresponding ftrace for this GuC id we can see:\n\n162.673311: xe_sched_msg_add: dev=0000:03:00.0, gt=1 guc_id=57, opcode=3\n162.673317: xe_sched_msg_recv: dev=0000:03:00.0, gt=1 guc_id=57, opcode=3\n162.673319: xe_exec_queue_scheduling_disable: dev=0000:03:00.0, 1:0x2, gt=1, width=1, guc_id=57, guc_state=0x29, flags=0x0\n162.674089: xe_exec_queue_kill: dev=0000:03:00.0, 1:0x2, gt=1, width=1, guc_id=57, guc_state=0x29, flags=0x0\n162.674108: xe_exec_queue_close: dev=0000:03:00.0, 1:0x2, gt=1, width=1, guc_id=57, guc_state=0xa9, flags=0x0\n162.674488: xe_exec_queue_scheduling_done: dev=0000:03:00.0, 1:0x2, gt=1, width=1, guc_id=57, guc_state=0xa9, flags=0x0\n162.678452: xe_exec_queue_deregister: dev=0000:03:00.0, 1:0x2, gt=1, width=1, guc_id=57, guc_state=0xa1, flags=0x0\n\nIt looks like we try to suspend the queue (opcode=3), setting\nsuspend_pending and triggering a disable_scheduling. The user then\ncloses the queue. However the close will also forcefully signal the\nsuspend fence after killing the queue, later when the G2H response for\ndisable_scheduling comes back we have now cleared suspend_pending when\nsignalling the suspend fence, so the disable_scheduling now incorrectly\ntries to also deregister the queue. This leads to warnings since the queue\nhas yet to even be marked for destruction. We also seem to trigger\nerrors later with trying to double unregister the same queue.\n\nTo fix this tweak the ordering when handling the response to ensure we\ndon't race with a disable_scheduling that didn't actually intend to\nperform an unregister. The destruction path should now also correctly\nwait for any pending_disable before marking as destroyed.\n\n(cherry picked from commit f161809b362f027b6d72bd998e47f8f0bad60a2e)" } ], "metrics": [ { "cvssV3_1": { "version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH" }, "scenarios": [ { "lang": "en", "value": "AV:L - The race is driven entirely through Intel Xe DRM ioctls (`XE_VM_BIND`/`XE_EXEC` triggering preempt-fence suspend, and `XE_EXEC_QUEUE_DESTROY`) on the local `/dev/dri/renderD*` node. No network or adjacent-network path reaches `xe_guc_submit.c`.\nAC:L - The attacker owns both sides of the race — it issues the operation that sets `suspend_pending` and fires `disable_scheduling()`, then closes the queue from another thread inside the GuC round-trip window, which the reported ftrace shows is ~1.2 ms wide. It reproduces in ordinary IGT test runs and can be looped across many exec queues concurrently until it lands.\nPR:L - Every ioctl on the path (`XE_VM_CREATE`, `XE_EXEC_QUEUE_CREATE`, `XE_VM_BIND`, `XE_EXEC`, `XE_EXEC_QUEUE_DESTROY`) is flagged `DRM_RENDER_ALLOW`, so any unprivileged process holding the render node — every GPU-using app on a desktop, Android, or ChromeOS system, including sandboxed browser GPU processes and containers with GPU passthrough — can reach it. No capability or DRM_MASTER is required.\nUI:N - A single unprivileged process performs the suspend-inducing operation and the queue destroy from its own threads. No victim action or cooperating user is involved.\nS:U - The corrupted state, freed objects, and resulting GT reset are all within the kernel's own security authority on the host. No VM, IOMMU, or hypervisor boundary is crossed.\nC:H - The out-of-protocol deregister lets `handle_deregister_done()` run against a queue whose lifetime the driver still owns, producing double `kfree(ge)`/`xe_exec_queue_fini(q)` and — once `release_guc_id()` recycles the id — a stale `DEREGISTER_DONE` landing on a different live queue. That use-after-free over attacker-shaped heap objects yields a read primitive into freed kernel memory.\nI:H - The same double-deregister drives `__guc_exec_queue_fini()` twice, re-running `INIT_WORK` on an already-queued work item and double-freeing `xe_guc_exec_queue`/`xe_exec_queue`, giving a write primitive into reclaimed slab memory that is exploitable for control-flow hijack via heap spraying.\nA:H - Confirmed WARN/assert splat plus permanent driver-versus-GuC state desync: the rejected `DEREGISTER_DONE` (`-EPROTO`) leaks the exec queue, its guc_id and its G2H credit forever, the follow-up `DISABLE` to an already-deregistered context times out into `xe_gt_reset_async()` killing all GPU contexts on the tile, and `show_run_ticks()`'s untimed `wait_var_event()` on `pending_removal` hangs fdinfo readers in unkillable uninterruptible sleep." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "drivers/gpu/drm/xe/xe_guc_submit.c" ], "versions": [ { "version": "dd08ebf6c3525a7ea2186e636df064ea47281987", "lessThan": "5ddcb50b700221fa7d7be2adcb3d7d7afe8633dd", "status": "affected", "versionType": "git" }, { "version": "dd08ebf6c3525a7ea2186e636df064ea47281987", "lessThan": "87651f31ae4e6e6e7e6c7270b9b469405e747407", "status": "affected", "versionType": "git" } ] }, { "product": "Linux", "vendor": "Linux", "defaultStatus": "affected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "drivers/gpu/drm/xe/xe_guc_submit.c" ], "versions": [ { "version": "6.8", "status": "affected" }, { "version": "0", "lessThan": "6.8", "status": "unaffected", "versionType": "semver" }, { "version": "6.12.4", "lessThanOrEqual": "6.12.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.13", "lessThanOrEqual": "*", "status": "unaffected", "versionType": "original_commit_for_fix" } ] } ], "cpeApplicability": [ { "nodes": [ { "operator": "OR", "negate": false, "cpeMatch": [ { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.8", "versionEndExcluding": "6.12.4" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.8", "versionEndExcluding": "6.13" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/5ddcb50b700221fa7d7be2adcb3d7d7afe8633dd" }, { "url": "https://git.kernel.org/stable/c/87651f31ae4e6e6e7e6c7270b9b469405e747407" } ], "title": "drm/xe/guc_submit: fix race around suspend_pending", "x_generator": { "engine": "bippy-1.2.0" } } } }