firmware: arm_scmi: Rework clock domain info lookups
authorCristian Marussi <cristian.marussi@arm.com>
Wed, 10 Jan 2024 12:09:16 +0000 (12:09 +0000)
committerSudeep Holla <sudeep.holla@arm.com>
Tue, 20 Feb 2024 06:29:31 +0000 (06:29 +0000)
Accessing clock domains descriptors by the index from the SCMI drivers
can potentially lead to out-of-bound violations if the SCMI drivers
misbehaves.

Use a common helper to check the consistency of such accesses.

Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20240110120916.2482603-1-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_scmi/clock.c

index e2050adbf85c6a125fc5ba241fb0c6b133466bfe..2e4d6479a639527fb4fd763cded63bf08c8408d2 100644 (file)
@@ -167,6 +167,15 @@ static enum scmi_clock_protocol_cmd evt_2_cmd[] = {
        CLOCK_RATE_CHANGE_REQUESTED_NOTIFY,
 };
 
+static inline struct scmi_clock_info *
+scmi_clock_domain_lookup(struct clock_info *ci, u32 clk_id)
+{
+       if (clk_id >= ci->num_clocks)
+               return ERR_PTR(-EINVAL);
+
+       return ci->clk + clk_id;
+}
+
 static int
 scmi_clock_protocol_attributes_get(const struct scmi_protocol_handle *ph,
                                   struct clock_info *ci)
@@ -580,10 +589,9 @@ scmi_clock_set_parent(const struct scmi_protocol_handle *ph, u32 clk_id,
        struct clock_info *ci = ph->get_priv(ph);
        struct scmi_clock_info *clk;
 
-       if (clk_id >= ci->num_clocks)
-               return -EINVAL;
-
-       clk = ci->clk + clk_id;
+       clk = scmi_clock_domain_lookup(ci, clk_id);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
 
        if (parent_id >= clk->num_parents)
                return -EINVAL;
@@ -800,10 +808,10 @@ scmi_clock_info_get(const struct scmi_protocol_handle *ph, u32 clk_id)
        struct scmi_clock_info *clk;
        struct clock_info *ci = ph->get_priv(ph);
 
-       if (clk_id >= ci->num_clocks)
+       clk = scmi_clock_domain_lookup(ci, clk_id);
+       if (IS_ERR(clk))
                return NULL;
 
-       clk = ci->clk + clk_id;
        if (!clk->name[0])
                return NULL;