drm/amd/ras: add length check for ras command output buffer

Add length check for ras command output buffer.

Signed-off-by: YiPeng Chai <YiPeng.Chai@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
YiPeng Chai 2026-05-19 13:46:55 +08:00 committed by Alex Deucher
parent 642ed3af44
commit 2206e6c76d
3 changed files with 24 additions and 11 deletions

View File

@ -139,7 +139,8 @@ static int amdgpu_ras_get_ras_safe_fb_addr_ranges(struct ras_core_context *ras_c
struct amdgpu_mem_partition_info *mem_ranges;
uint32_t i = 0;
if (cmd->input_size != sizeof(*input_data))
if ((cmd->input_size != sizeof(*input_data)) ||
(cmd->output_buf_size < sizeof(*ranges)))
return RAS_CMD__ERROR_INVALID_INPUT_DATA;
mem_ranges = adev->gmc.mem_partitions;
@ -207,7 +208,8 @@ static int amdgpu_ras_translate_fb_address(struct ras_core_context *ras_core,
(struct ras_cmd_translate_fb_address_rsp *)cmd->output_buff_raw;
int ret = RAS_CMD__ERROR_GENERIC;
if (cmd->input_size != sizeof(struct ras_cmd_translate_fb_address_req))
if ((cmd->input_size != sizeof(struct ras_cmd_translate_fb_address_req)) ||
(cmd->output_buf_size < sizeof(*rsp_buff)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
if ((req_buff->src_addr_type >= RAS_FB_ADDR_UNKNOWN) ||
@ -279,7 +281,7 @@ int amdgpu_ras_submit_cmd(struct ras_core_context *ras_core, struct ras_cmd_ctx
cmd->cmd_res = res;
if (cmd->output_size > cmd->output_buf_size) {
if (!res && (cmd->output_size > cmd->output_buf_size)) {
RAS_DEV_ERR(cmd_core->dev,
"Output size 0x%x exceeds output buffer size 0x%x!\n",
cmd->output_size, cmd->output_buf_size);

View File

@ -261,7 +261,8 @@ static int amdgpu_virt_ras_get_cper_records(struct ras_core_context *ras_core,
uint8_t *out_buf;
int ret = 0, i, count;
if (cmd->input_size != sizeof(struct ras_cmd_cper_record_req))
if (cmd->input_size != sizeof(struct ras_cmd_cper_record_req) ||
(cmd->output_buf_size < sizeof(*rsp)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
if (!req->buf_size || !req->buf_ptr || !req->cper_num ||
@ -471,7 +472,7 @@ int amdgpu_virt_ras_handle_cmd(struct ras_core_context *ras_core,
cmd->cmd_res = res;
if (cmd->output_size > cmd->output_buf_size) {
if (!res && (cmd->output_size > cmd->output_buf_size)) {
RAS_DEV_ERR(ras_core->dev,
"Output data size 0x%x exceeds buffer size 0x%x!\n",
cmd->output_size, cmd->output_buf_size);

View File

@ -38,7 +38,8 @@ static int ras_get_block_ecc_info(struct ras_core_context *ras_core,
struct ras_ecc_count err_data;
int ret;
if (cmd->input_size != sizeof(struct ras_cmd_block_ecc_info_req))
if ((cmd->input_size != sizeof(struct ras_cmd_block_ecc_info_req)) ||
(cmd->output_buf_size < sizeof(*output_data)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
memset(&err_data, 0, sizeof(err_data));
@ -122,7 +123,8 @@ static int ras_cmd_get_bad_pages(struct ras_core_context *ras_core,
(struct ras_cmd_bad_pages_info_rsp *)cmd->output_buff_raw;
int ret;
if (cmd->input_size != sizeof(struct ras_cmd_bad_pages_info_req))
if ((cmd->input_size != sizeof(struct ras_cmd_bad_pages_info_req)) ||
(cmd->output_buf_size < sizeof(*output_data)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
ret = ras_cmd_get_group_bad_pages(ras_core, input_data->group_index, output_data);
@ -177,7 +179,8 @@ static int ras_cmd_get_cper_snapshot(struct ras_core_context *ras_core,
(struct ras_cmd_cper_snapshot_rsp *)cmd->output_buff_raw;
struct ras_log_batch_overview overview;
if (cmd->input_size != sizeof(struct ras_cmd_cper_snapshot_req))
if ((cmd->input_size != sizeof(struct ras_cmd_cper_snapshot_req)) ||
(cmd->output_buf_size < sizeof(*output_data)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
ras_log_ring_get_batch_overview(ras_core, &overview);
@ -206,7 +209,8 @@ static int ras_cmd_get_cper_records(struct ras_core_context *ras_core,
uint8_t *buffer;
int ret = 0, i, count;
if (cmd->input_size != sizeof(struct ras_cmd_cper_record_req))
if ((cmd->input_size != sizeof(struct ras_cmd_cper_record_req)) ||
(cmd->output_buf_size < sizeof(*rsp)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
if (!req->buf_size || !req->buf_ptr || !req->cper_num ||
@ -261,7 +265,8 @@ static int ras_cmd_get_batch_trace_snapshot(struct ras_core_context *ras_core,
struct ras_log_batch_overview overview;
if (cmd->input_size != sizeof(struct ras_cmd_batch_trace_snapshot_req))
if ((cmd->input_size != sizeof(struct ras_cmd_batch_trace_snapshot_req)) ||
(cmd->output_buf_size < sizeof(*rsp)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
ras_log_ring_get_batch_overview(ras_core, &overview);
@ -289,7 +294,8 @@ static int ras_cmd_get_batch_trace_records(struct ras_core_context *ras_core,
uint64_t id;
bool completed = false;
if (cmd->input_size != sizeof(struct ras_cmd_batch_trace_record_req))
if ((cmd->input_size != sizeof(struct ras_cmd_batch_trace_record_req)) ||
(cmd->output_buf_size < sizeof(*output_data)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
if ((!input_data->batch_num) || (input_data->batch_num > RAS_CMD_MAX_BATCH_NUM))
@ -416,6 +422,10 @@ static int ras_cmd_inject_error(struct ras_core_context *ras_core,
.value = req->method,
};
if ((cmd->input_size != sizeof(*req)) ||
(cmd->output_buf_size < sizeof(*output_data)))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
ret = ras_psp_trigger_error(ras_core, &block_info, req->instance_mask);
if (!ret) {
output_data->version = 0;