mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
drm/amdgpu: Fix TOCTOU on UniRAS command response size
The guest maps the PF response in shared VRAM (struct ras_cmd_ctx in the command buffer). After amdgpu_virt_send_remote_ras_cmd() returns, the code validated rcmd->output_size against the caller buffer, then copied rcmd->output_buff_raw using rcmd->output_size again. A malicious PF could change output_size between those reads so the memcpy length exceeds the caller’s output_size and overflows guest stack or heap buffers. Snapshot output_size with READ_ONCE() once, assign cmd->output_size from that value, and use the same snapshot for the bounds check and memcpy. Also read cmd_res once with READ_ONCE() so the error branch and cmd->cmd_res assignment do not observe different values from shared memory. Signed-off-by: Chenglei Xie <Chenglei.Xie@amd.com> Reviewed-by: YiPeng Chai <YiPeng.Chai@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
ebbd73d089
commit
26057fb8e1
|
|
@ -108,15 +108,19 @@ static int amdgpu_virt_ras_remote_ioctl_cmd(struct ras_core_context *ras_core,
|
|||
ret = amdgpu_virt_send_remote_ras_cmd(ras_core->dev,
|
||||
shared_mem.gpa, mem_len);
|
||||
if (!ret) {
|
||||
if (rcmd->cmd_res) {
|
||||
ret = rcmd->cmd_res;
|
||||
uint32_t cmd_res = READ_ONCE(rcmd->cmd_res);
|
||||
uint32_t osz;
|
||||
|
||||
if (cmd_res) {
|
||||
ret = cmd_res;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmd->cmd_res = rcmd->cmd_res;
|
||||
cmd->output_size = rcmd->output_size;
|
||||
if (rcmd->output_size && (rcmd->output_size <= output_size) && output_data)
|
||||
memcpy(output_data, rcmd->output_buff_raw, rcmd->output_size);
|
||||
osz = READ_ONCE(rcmd->output_size);
|
||||
cmd->cmd_res = cmd_res;
|
||||
cmd->output_size = osz;
|
||||
if (osz && osz <= output_size && output_data)
|
||||
memcpy(output_data, rcmd->output_buff_raw, osz);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user