[PATCH 2/4] firmware: arm_scmi: Validate BASE_ERROR_EVENT payload size
Sudeep Holla
sudeep.holla at kernel.org
Sun May 17 12:02:41 PDT 2026
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.
Signed-off-by: Sudeep Holla <sudeep.holla at kernel.org>
---
drivers/firmware/arm_scmi/base.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index 4df2620e3c5d..d08a4f6a9ced 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 = sizeof(p->agent_id) + sizeof(p->error_status);
+ 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;
--
2.43.0
More information about the linux-arm-kernel
mailing list