diff options
| author | Chenglei Xie <Chenglei.Xie@amd.com> | 2026-05-07 23:16:58 +0300 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-05-19 01:13:37 +0300 |
| commit | c06b6cde2a1c3bcbb561bd57bb6f34eae9030921 (patch) | |
| tree | 3917564fc29046c66cb9c3aeec0bd3371ebb6db4 | |
| parent | 3635e1104aa21a01c2e6e7dde02a5b3641f4c46c (diff) | |
| download | linux-c06b6cde2a1c3bcbb561bd57bb6f34eae9030921.tar.xz | |
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>
| -rw-r--r-- | drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c index fb4d375e87b2..4021259115cc 100644 --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c @@ -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; } |
