mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
drm/amdgpu: fix OOB risk parsing virt RAS batch trace replies on the VF
amdgpu_virt_ras_get_batch_records() indexed batchs[] and records[] from ras_cmd_batch_trace_record_rsp copied out of shared memory without fully bounding the cache window or per-batch offset/trace_num. A tampered or corrupted buffer could set real_batch_num past the array, make a naive start_batch_id + real_batch_num comparison wrap in uint64_t, or point offset+trace_num past records[]. Add amdgpu_virt_ras_check_batch_cached() for a subtraction-based window with a real_batch_num cap, re-run it after GET_BATCH_TRACE_RECORD, and use an explicit batch index into batchs[]. Consolidate batch_id, trace_num, and offset+trace_num checks; on any failure memset the cache and return -EIO so the next call refetches. 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
3635e1104a
commit
c06b6cde2a
|
|
@ -192,6 +192,15 @@ static int amdgpu_virt_ras_get_cper_snapshot(struct ras_core_context *ras_core,
|
|||
return RAS_CMD__SUCCESS;
|
||||
}
|
||||
|
||||
static bool amdgpu_virt_ras_check_batch_cached(struct ras_cmd_batch_trace_record_rsp *rsp,
|
||||
uint64_t batch_id)
|
||||
{
|
||||
return rsp->real_batch_num &&
|
||||
rsp->real_batch_num <= RAS_CMD_MAX_BATCH_NUM &&
|
||||
batch_id >= rsp->start_batch_id &&
|
||||
(batch_id - rsp->start_batch_id) < rsp->real_batch_num;
|
||||
}
|
||||
|
||||
static int amdgpu_virt_ras_get_batch_records(struct ras_core_context *ras_core, uint64_t batch_id,
|
||||
struct ras_log_info **trace_arr, uint32_t arr_num,
|
||||
struct ras_cmd_batch_trace_record_rsp *rsp_cache)
|
||||
|
|
@ -204,26 +213,32 @@ static int amdgpu_virt_ras_get_batch_records(struct ras_core_context *ras_core,
|
|||
struct batch_ras_trace_info *batch;
|
||||
int ret = 0;
|
||||
uint32_t i;
|
||||
uint32_t idx;
|
||||
|
||||
if (!rsp->real_batch_num || (batch_id < rsp->start_batch_id) ||
|
||||
(batch_id >= (rsp->start_batch_id + rsp->real_batch_num))) {
|
||||
|
||||
if (!amdgpu_virt_ras_check_batch_cached(rsp, batch_id)) {
|
||||
memset(rsp, 0, sizeof(*rsp));
|
||||
ret = amdgpu_virt_ras_send_remote_cmd(ras_core, RAS_CMD__GET_BATCH_TRACE_RECORD,
|
||||
&req, sizeof(req), rsp, sizeof(*rsp));
|
||||
if (ret)
|
||||
return -EPIPE;
|
||||
|
||||
if (!amdgpu_virt_ras_check_batch_cached(rsp, batch_id)) {
|
||||
memset(rsp, 0, sizeof(*rsp));
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
batch = &rsp->batchs[batch_id - rsp->start_batch_id];
|
||||
if (batch_id != batch->batch_id)
|
||||
return -ENODATA;
|
||||
idx = (uint32_t)(batch_id - rsp->start_batch_id);
|
||||
batch = &rsp->batchs[idx];
|
||||
if (batch_id != batch->batch_id ||
|
||||
batch->trace_num > MAX_RECORD_PER_BATCH ||
|
||||
(uint32_t)batch->offset + batch->trace_num > RAS_CMD_MAX_TRACE_NUM) {
|
||||
memset(rsp, 0, sizeof(*rsp));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
for (i = 0; i < batch->trace_num; i++) {
|
||||
if (i >= arr_num)
|
||||
break;
|
||||
for (i = 0; i < batch->trace_num && i < arr_num; i++)
|
||||
trace_arr[i] = &rsp->records[batch->offset + i];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user