]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
firmware: ti_sci: Fix memory leaks in devm_ti_sci_get_of_resource
authorFrancois Berder <fberder@outlook.fr>
Tue, 11 Nov 2025 10:30:19 +0000 (11:30 +0100)
committerTom Rini <trini@konsulko.com>
Fri, 5 Dec 2025 22:23:49 +0000 (16:23 -0600)
- Fix temp memory leak
- Free memory during error handling

Signed-off-by: Francois Berder <fberder@outlook.fr>
drivers/firmware/ti_sci.c

index 6f57dcfe8de8f874318cd53372c798d182faae73..0f5e180e9e945950739338cfbe4f70ffd1c3a200 100644 (file)
@@ -3083,23 +3083,33 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
        sets = dev_read_size(dev, of_prop);
        if (sets < 0) {
                dev_err(dev, "%s resource type ids not available\n", of_prop);
+               devm_kfree(dev, res);
                return ERR_PTR(sets);
        }
        temp = devm_kmalloc(dev, sets, GFP_KERNEL);
-       if (!temp)
+       if (!temp) {
+               devm_kfree(dev, res);
                return ERR_PTR(-ENOMEM);
+       }
 
        sets /= sizeof(u32);
        res->sets = sets;
 
        res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
                                 GFP_KERNEL);
-       if (!res->desc)
+       if (!res->desc) {
+               devm_kfree(dev, temp);
+               devm_kfree(dev, res);
                return ERR_PTR(-ENOMEM);
+       }
 
        ret = dev_read_u32_array(dev, of_prop, temp, res->sets);
-       if (ret)
+       if (ret) {
+               devm_kfree(dev, temp);
+               devm_kfree(dev, res->desc);
+               devm_kfree(dev, res);
                return ERR_PTR(-EINVAL);
+       }
 
        for (i = 0; i < res->sets; i++) {
                resource_subtype = temp[i];
@@ -3124,14 +3134,30 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
                res->desc[i].res_map =
                        devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) *
                                     sizeof(*res->desc[i].res_map), GFP_KERNEL);
-               if (!res->desc[i].res_map)
+               if (!res->desc[i].res_map) {
+                       int j;
+
+                       devm_kfree(dev, temp);
+
+                       for (j = 0; j < i; j++)
+                               devm_kfree(dev, res->desc[j].res_map);
+
+                       devm_kfree(dev, res->desc);
+                       devm_kfree(dev, res);
                        return ERR_PTR(-ENOMEM);
+               }
        }
 
        devm_kfree(dev, temp);
        if (valid_set)
                return res;
 
+       for (i = 0; i < res->sets; i++)
+               devm_kfree(dev, res->desc[i].res_map);
+
+       devm_kfree(dev, res->desc);
+       devm_kfree(dev, res);
+
        return ERR_PTR(-EINVAL);
 }