From: YiPeng Chai Date: Tue, 19 May 2026 05:46:55 +0000 (+0800) Subject: drm/amd/ras: add length check for ras command output buffer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2206e6c76d05e30447330d00c324fa03e35e4f0c;p=thirdparty%2Flinux.git drm/amd/ras: add length check for ras command output buffer Add length check for ras command output buffer. Signed-off-by: YiPeng Chai Reviewed-by: Tao Zhou Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c index cb6498c30834..c22e53e84207 100644 --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c @@ -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); 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 daad99a46263..6ef9ec7ed597 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 @@ -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); diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_cmd.c b/drivers/gpu/drm/amd/ras/rascore/ras_cmd.c index 405154ff13cf..e3b0c8b06c1c 100644 --- a/drivers/gpu/drm/amd/ras/rascore/ras_cmd.c +++ b/drivers/gpu/drm/amd/ras/rascore/ras_cmd.c @@ -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;