[PATCH v2] scmi: reset: validate number of reset domains

Artem Shimko
2025-11-03T16:10:54Z

Add validation to reject zero reset domains during protocol initialization.

The fix adds an explicit check for zero domains in
scmi_reset_protocol_init(), returning -EINVAL early during protocol
initialization. This prevents the driver from proceeding with a
non-functional state and avoids potential kernel panics in functions
like scmi_reset_domain_reset() and scmi_reset_notify_supported() that
assume dom_info is always valid.

The change is minimal and safe, affecting only the error case while
preserving all existing functionality for valid configurations.
The existing -ENOMEM handling for memory allocation remains unchanged
and sufficient.

This change ensures early failure with -EINVAL during protocol
initialization, preventing silent failures and maintaining system
stability. The existing -ENOMEM handling for memory allocation remains
unchanged and sufficient.

Signed-off-by: Artem Shimko <a.shimko.dev@gmail.com>
---
Dear SCMI Maintainers,

This patch addresses an issue in the SCMI reset protocol initialization
where a zero value for num_domains could lead to a non-functional state
or potential NULL pointer dereferences.

Currently, if the platform reports zero reset domains, the driver
continues initialization but creates an inconsistent state:

ret = scmi_reset_attributes_get(ph, pinfo);
if (ret)
return ret;

/* When num_domains == 0: */
pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains, /* 0 */
sizeof(*pinfo->dom_info), GFP_KERNEL);
/* Returns ZERO_SIZE_PTR (not NULL) */

if (!pinfo->dom_info) /* ZERO_SIZE_PTR != NULL, condition fails */
return -ENOMEM;

/* Execution continues! */
return ph->set_priv(ph, pinfo, version); /* Returns SUCCESS (0)! */

However, subsequent reset operations crash when accessing dom_info:

static int scmi_reset_domain_reset(const struct scmi_protocol_handle *ph,
u32 domain_id)
{
struct scmi_reset_info *pi = ph->get_priv(ph);
struct reset_dom_info *dom = pi->dom_info + domain_id;
/* ZERO_SIZE_PTR + domain_id = INVALID POINTER! */
/* KERNEL PANIC on dom-> access */
}

The protocol appears to initialize successfully but is actually non-functional
and will crash on first usage.

The patch adds validation to reject zero domains during initialization,
ensuring fail-fast behavior and preventing hidden failures. This approach
maintains system stability by catching invalid configurations early.

Testing confirmed normal operation with positive num_domains values and
proper error handling with zero domains. The change is minimal and safe,
affecting only the error case while preserving all existing functionality
for valid configurations.

This patch fixes a potential crash scenario while maintaining full
backward compatibility with properly configured systems.

If this is a working case, I will check and supplement other protocols such as
sensor and power domain.
--
Best regards,
Artem Shimko

ChangeLog:
v2: Change commit message

drivers/firmware/arm_scmi/reset.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c
index 0aa82b96f41b..458b75fcc858 100644
--- a/drivers/firmware/arm_scmi/reset.c
+++ b/drivers/firmware/arm_scmi/reset.c
@@ -358,6 +358,9 @@ static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph)
if (ret)
return ret;

+ if (!pinfo->num_domains)
+ return -EINVAL;
+
pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains,
sizeof(*pinfo->dom_info), GFP_KERNEL);
if (!pinfo->dom_info)
--
2.43.0