[PATCH v2] pinctrl: generic: free maps on pinctrl_generic_to_map() failure

[email protected]
Newsgroups org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Surendra Singh Chouhan <[email protected]>

pinctrl_generic_to_map() parses DT configuration and allocates pinctrl
maps via pinctrl_utils_reserve_map().

If subsequent steps (such as pinctrl_utils_add_map_mux(),
pinctrl_generic_add_group(), pinconf_generic_parse_dt_config(), or
pinctrl_utils_add_map_configs()) return an error, *maps may contain
partially allocated map entries. Returning the error directly without
freeing *maps leaks the allocated mapping memory across all drivers
that rely on pinctrl_generic_to_map().

Fix this by calling pinctrl_utils_free_map() and resetting *maps,
*num_maps, and *num_reserved_maps in the error path of
pinctrl_generic_to_map().

Fixes: aaaf31be0426 ("pinctrl: extract pinctrl_generic_to_map() from pinctrl_generic_pins_function_dt_node_to_map()")
Signed-off-by: Surendra Singh Chouhan <[email protected]>
---
v2:
 - Move map cleanup inside pinctrl_generic_to_map() helper in pinctrl-generic.c
   so all callers are protected from memory leaks, as suggested by Frank Li.

 drivers/pinctrl/pinctrl-generic-mux.c |  4 +---
 drivers/pinctrl/pinctrl-generic.c     | 27 +++++++++++++++++++--------
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-generic-mux.c b/drivers/pinctrl/pinctrl-generic-mux.c
index 927c7aa616f5..da5a5ec01583 100644
--- a/drivers/pinctrl/pinctrl-generic-mux.c
+++ b/drivers/pinctrl/pinctrl-generic-mux.c
@@ -58,10 +58,8 @@ mux_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,
 				     num_maps, &num_reserved_maps, group_names,
 				     0, &np_config->name, NULL, 0);
 
-	if (ret) {
-		pinctrl_utils_free_map(pctldev, *maps, *num_maps);
+	if (ret)
 		return ret;
-	}
 
 	ret = pinmux_generic_add_function(pctldev, np_config->name, group_names,
 					  1, function);
diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
index 9759b0186bcc..d5f07f4a8b88 100644
--- a/drivers/pinctrl/pinctrl-generic.c
+++ b/drivers/pinctrl/pinctrl-generic.c
@@ -42,34 +42,45 @@ int pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *pare
 	ret = pinctrl_utils_add_map_mux(pctldev, maps, num_reserved_maps, num_maps, group_name,
 					parent->name);
 	if (ret < 0)
-		return ret;
+		goto err_free_map;
 
 	ret = pinctrl_generic_add_group(pctldev, group_name, pins, npins, data);
-	if (ret < 0)
-		return dev_err_probe(dev, ret, "failed to add group %s: %d\n",
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "failed to add group %s: %d\n",
 				     group_name, ret);
+		goto err_free_map;
+	}
 
 	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
-	if (ret)
-		return dev_err_probe(dev, ret, "failed to parse pin config of group %s\n",
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to parse pin config of group %s\n",
 			group_name);
+		goto err_free_map;
+	}
 
 	if (num_configs == 0)
 		return 0;
 
 	ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
 	if (ret)
-		return ret;
+		goto err_free_map;
 
 	ret = pinctrl_utils_add_map_configs(pctldev, maps, num_reserved_maps, num_maps, group_name,
 					    configs,
 			num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
 	kfree(configs);
 	if (ret)
-		return ret;
+		goto err_free_map;
 
 	return 0;
-};
+
+err_free_map:
+	pinctrl_utils_free_map(pctldev, *maps, *num_maps);
+	*maps = NULL;
+	*num_maps = 0;
+	*num_reserved_maps = 0;
+	return ret;
+}
 EXPORT_SYMBOL_GPL(pinctrl_generic_to_map);
 
 static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.