From: Bartosz Golaszewski bartosz.golaszewski@linaro.org
[ Upstream commit aae7a2876c3b39d07aa7655ea082af8e7862f3a5 ]
Unlike all the other allocations in this driver, the memory for storing the pin function descriptions allocated with kcalloc() and later resized with krealloc() is never freed. Use devres like elsewhere to handle that. While at it - replace krealloc() with more suitable devm_krealloc_array().
Note: the logic in this module is pretty convoluted and could probably use some revisiting, we should probably be able to calculate the exact amount of memory needed in advance or even skip the allocation altogether and just add each function to the radix tree separately.
Tested-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Bartosz Golaszewski bartosz.golaszewski@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES - `keembay_build_functions()` currently grabs `kcalloc()`ed storage for the temporary `struct function_desc` array and then drops the pointer once `keembay_add_functions()` runs, so nothing ever frees that memory on driver unload (`drivers/pinctrl/pinctrl-keembay.c:1609`). The original driver commit (`ffd4e739358be`) introduced this leak, so all released kernels inherit it. - The patch converts that allocation to `devm_kcalloc()` and the resize step to `devm_krealloc_array()` (`drivers/pinctrl/pinctrl- keembay.c:1609` and `drivers/pinctrl/pinctrl-keembay.c:1640`), letting devres reclaim the buffer automatically on probe failure or device detach instead of leaking `npins * 8 * sizeof(struct function_desc)` bytes each cycle. The explicit `kfree()` in the error path is removed because devm now owns the buffer (`drivers/pinctrl/pinctrl- keembay.c:1642`). - The driver already relies on devres for all other dynamic allocations (see the existing `devm_kcalloc()` for function group names at `drivers/pinctrl/pinctrl-keembay.c:1569`), so this aligns the remaining allocation with the established pattern. No behavioural or ABI changes accompany the fix, and `devm_krealloc_array()` is available in current stable code. - The bug affects real users whenever the pinctrl device is unbound (module reloads, hotplugged firmware, suspend failures, etc.), steadily leaking kernel memory. The fix is self-contained, low risk, and directly targets that leak without touching shared pinctrl infrastructure.
Given the tangible bugfix, limited scope, and minimal regression risk, this is a solid candidate for stable backporting.
drivers/pinctrl/pinctrl-keembay.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-keembay.c b/drivers/pinctrl/pinctrl-keembay.c index 60cf017498b32..6aefcbc313099 100644 --- a/drivers/pinctrl/pinctrl-keembay.c +++ b/drivers/pinctrl/pinctrl-keembay.c @@ -1603,7 +1603,8 @@ static int keembay_build_functions(struct keembay_pinctrl *kpc) * being part of 8 (hw maximum) globally unique muxes. */ kpc->nfuncs = 0; - keembay_funcs = kcalloc(kpc->npins * 8, sizeof(*keembay_funcs), GFP_KERNEL); + keembay_funcs = devm_kcalloc(kpc->dev, kpc->npins * 8, + sizeof(*keembay_funcs), GFP_KERNEL); if (!keembay_funcs) return -ENOMEM;
@@ -1634,7 +1635,9 @@ static int keembay_build_functions(struct keembay_pinctrl *kpc) }
/* Reallocate memory based on actual number of functions */ - new_funcs = krealloc(keembay_funcs, kpc->nfuncs * sizeof(*new_funcs), GFP_KERNEL); + new_funcs = devm_krealloc_array(kpc->dev, keembay_funcs, + kpc->nfuncs, sizeof(*new_funcs), + GFP_KERNEL); if (!new_funcs) { kfree(keembay_funcs); return -ENOMEM;