diff options
| author | Francois Berder <[email protected]> | 2025-11-11 11:30:19 +0100 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-12-05 16:23:49 -0600 |
| commit | 00e1fed93c8c3e4c9037741ea1b70a9e693a6e65 (patch) | |
| tree | d463323c0b0c49f3ef28d365283a8cd469a24d7a /drivers | |
| parent | 9d69a2d8a092abab761f57795e906a7a579b3a00 (diff) | |
firmware: ti_sci: Fix memory leaks in devm_ti_sci_get_of_resource
- Fix temp memory leak
- Free memory during error handling
Signed-off-by: Francois Berder <[email protected]>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/firmware/ti_sci.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 6f57dcfe8de..0f5e180e9e9 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -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); } |
