From: Sudeep Holla Date: Sun, 17 May 2026 19:02:41 +0000 (+0100) Subject: firmware: arm_scmi: Validate BASE_ERROR_EVENT payload size X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56e7e64cdd0e7209a58c8ec66028d63387402919;p=thirdparty%2Fkernel%2Flinux.git firmware: arm_scmi: Validate BASE_ERROR_EVENT payload size BASE_ERROR_EVENT carries a variable number of message reports, with the count encoded in error_status. The notification parser used that count without checking whether the received payload contained all reported entries. Reject truncated payloads before copying the report array. Link: https://patch.msgid.link/20260517-scmi_fixes-v1-2-d86daec4defd@kernel.org Signed-off-by: Sudeep Holla --- diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c index 4df2620e3c5d0..a9cea09355ff4 100644 --- a/drivers/firmware/arm_scmi/base.c +++ b/drivers/firmware/arm_scmi/base.c @@ -325,6 +325,8 @@ static void *scmi_base_fill_custom_report(const struct scmi_protocol_handle *ph, void *report, u32 *src_id) { int i; + u32 error_status; + size_t expected_sz; const struct scmi_base_error_notify_payld *p = payld; struct scmi_base_error_report *r = report; @@ -338,10 +340,19 @@ static void *scmi_base_fill_custom_report(const struct scmi_protocol_handle *ph, if (evt_id != SCMI_EVENT_BASE_ERROR_EVENT || sizeof(*p) < payld_sz) return NULL; + expected_sz = offsetof(typeof(*p), msg_reports); + if (payld_sz < expected_sz) + return NULL; + r->timestamp = timestamp; r->agent_id = le32_to_cpu(p->agent_id); - r->fatal = IS_FATAL_ERROR(le32_to_cpu(p->error_status)); - r->cmd_count = ERROR_CMD_COUNT(le32_to_cpu(p->error_status)); + error_status = le32_to_cpu(p->error_status); + r->fatal = IS_FATAL_ERROR(error_status); + r->cmd_count = ERROR_CMD_COUNT(error_status); + expected_sz += r->cmd_count * sizeof(p->msg_reports[0]); + if (payld_sz < expected_sz) + return NULL; + for (i = 0; i < r->cmd_count; i++) r->reports[i] = le64_to_cpu(p->msg_reports[i]); *src_id = 0;