CVE-2026-97496: drm/amdkfd: Fix OOB memory exposure in get_wave_state()
In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: Fix OOB memory exposure in getwavestate()
The getwavestate() function for v9 trusts cphqdcntlstacksize and cphqdcntlstackoffset values read directly from the MQD, which are written by GPU microcode and fully attacker-controlled on the CRIU-restore path (via AMDKFDIOCRESTOREPROCESS with H3).
this leads to an unbounded copytouser() that can leak adjacent GTT/kernel memory. If offset > size, integer underflow produces a ~4 GiB read length, if size is set to 1 MiB against a 4 KiB allocation, we leak 1 MiB of adjacent kernel memory (other queues' MQDs, ring buffers, KASLR pointers).
Fix by clamping both cphqdcntlstacksize to the actual allocated buffer size (q->ctlstacksize) and cphqdcntlstackoffset to the clamped size before performing arithmetic and copytouser().
This ensures we never read beyond the allocated kernel BO regardless of attacker-supplied MQD field values.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
In the v9 get_wave_state() CRIU-restore path, clamp cp_hqd_cntl_stack_size to the actual allocated buffer size (q->ctl_stack_size) and clamp cp_hqd_cntl_stack_offset to the clamped size before performing arithmetic and copy_to_user().
Event History
Frequently Asked Questions
Who is exposed to this issue?
Systems using the Linux kernel AMDKFD driver are exposed where an attacker can reach the CRIU restore path through AMDKFD_IOC_RESTORE_PROCESS with H3. The issue concerns GPU queue state restored from attacker-controlled MQD fields.
What does an attacker need to exploit it?
The attacker needs control over the cp_hqd_cntl_stack_size and cp_hqd_cntl_stack_offset values in an MQD supplied on the CRIU-restore path. Those values can cause get_wave_state() to copy memory beyond the allocated control-stack buffer to user space.
What can be disclosed if exploitation succeeds?
The out-of-bounds copy can expose adjacent GTT or kernel memory. The described examples include other queues' MQDs, ring buffers, and KASLR pointers.
How does the fix prevent the exposure?
The fix clamps the MQD-provided stack size to the actual allocated buffer size, q->ctl_stack_size, and clamps the offset to that resulting size before arithmetic and copy_to_user(). This prevents reads beyond the allocated kernel buffer even when the MQD fields are attacker controlled.