Add length check for ras command output buffer.
Signed-off-by: YiPeng Chai <[email protected]>
---
.../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c | 8 ++++---
.../drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c | 5 +++--
drivers/gpu/drm/amd/ras/rascore/ras_cmd.c | 22 ++++++++++++++-----
3 files changed, 24 insertions(+), 11 deletions(-)
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 4775a56e47dc..b8e9442b2ca5 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
@@ -278,7 +278,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)
@@ -491,7 +492,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 1136db9e29c4..5b7a36596b02 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)
@@ -264,7 +268,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);
@@ -292,7 +297,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))
@@ -423,6 +429,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;
--
2.43.0