pinctrl: stm32: fix memory leak issue
authorAlexandre Torgue <alexandre.torgue@st.com>
Thu, 14 Feb 2019 16:54:24 +0000 (17:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2019 14:38:32 +0000 (15:38 +0100)
commit cd8c9b5a49576bf28990237715bc2cb2210ac80a upstream.

configs is allocated by pinconf_generic_parse_dt_config(),
pinctrl_utils_add_map_configs() duplicates configs so it can and has to
be freed to prevent memory leaks.

Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/pinctrl/stm32/pinctrl-stm32.c

index 50299ad966590e8ae0ce2813d1f803c790c6ce51..072bd11074c6f55f8f1cee9433aafc947b36cab7 100644 (file)
@@ -403,7 +403,7 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
        unsigned int num_configs;
        bool has_config = 0;
        unsigned reserve = 0;
-       int num_pins, num_funcs, maps_per_pin, i, err;
+       int num_pins, num_funcs, maps_per_pin, i, err = 0;
 
        pctl = pinctrl_dev_get_drvdata(pctldev);
 
@@ -430,41 +430,45 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
        if (has_config && num_pins >= 1)
                maps_per_pin++;
 
-       if (!num_pins || !maps_per_pin)
-               return -EINVAL;
+       if (!num_pins || !maps_per_pin) {
+               err = -EINVAL;
+               goto exit;
+       }
 
        reserve = num_pins * maps_per_pin;
 
        err = pinctrl_utils_reserve_map(pctldev, map,
                        reserved_maps, num_maps, reserve);
        if (err)
-               return err;
+               goto exit;
 
        for (i = 0; i < num_pins; i++) {
                err = of_property_read_u32_index(node, "pinmux",
                                i, &pinfunc);
                if (err)
-                       return err;
+                       goto exit;
 
                pin = STM32_GET_PIN_NO(pinfunc);
                func = STM32_GET_PIN_FUNC(pinfunc);
 
                if (!stm32_pctrl_is_function_valid(pctl, pin, func)) {
                        dev_err(pctl->dev, "invalid function.\n");
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto exit;
                }
 
                grp = stm32_pctrl_find_group_by_pin(pctl, pin);
                if (!grp) {
                        dev_err(pctl->dev, "unable to match pin %d to group\n",
                                        pin);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto exit;
                }
 
                err = stm32_pctrl_dt_node_to_map_func(pctl, pin, func, grp, map,
                                reserved_maps, num_maps);
                if (err)
-                       return err;
+                       goto exit;
 
                if (has_config) {
                        err = pinctrl_utils_add_map_configs(pctldev, map,
@@ -472,11 +476,13 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
                                        configs, num_configs,
                                        PIN_MAP_TYPE_CONFIGS_GROUP);
                        if (err)
-                               return err;
+                               goto exit;
                }
        }
 
-       return 0;
+exit:
+       kfree(configs);
+       return err;
 }
 
 static int stm32_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,