summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-axp209.c
diff options
context:
space:
mode:
authorAnton Vasilyev <vasilyev@ispras.ru>2018-08-06 12:06:35 -0400
committerLinus Walleij <linus.walleij@linaro.org>2018-08-10 17:12:43 -0400
commit504c76979bccec66e4c2e41f6a006e49e284466f (patch)
tree3382955b0359f03dd734682295b2bd628e339d9b /drivers/pinctrl/pinctrl-axp209.c
parent01f1974e5f08732de6cecc4287788a99cfc3b325 (diff)
pinctrl: axp209: Fix NULL pointer dereference after allocation
There is no check that allocation in axp20x_funcs_groups_from_mask is successful. The patch adds corresponding check and return values. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru> Acked-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-axp209.c')
-rw-r--r--drivers/pinctrl/pinctrl-axp209.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c
index a52779f33ad4..afd0b533c40a 100644
--- a/drivers/pinctrl/pinctrl-axp209.c
+++ b/drivers/pinctrl/pinctrl-axp209.c
@@ -316,7 +316,7 @@ static const struct pinctrl_ops axp20x_pctrl_ops = {
316 .get_group_pins = axp20x_group_pins, 316 .get_group_pins = axp20x_group_pins,
317}; 317};
318 318
319static void axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask, 319static int axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask,
320 unsigned int mask_len, 320 unsigned int mask_len,
321 struct axp20x_pinctrl_function *func, 321 struct axp20x_pinctrl_function *func,
322 const struct pinctrl_pin_desc *pins) 322 const struct pinctrl_pin_desc *pins)
@@ -331,18 +331,22 @@ static void axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask,
331 func->groups = devm_kcalloc(dev, 331 func->groups = devm_kcalloc(dev,
332 ngroups, sizeof(const char *), 332 ngroups, sizeof(const char *),
333 GFP_KERNEL); 333 GFP_KERNEL);
334 if (!func->groups)
335 return -ENOMEM;
334 group = func->groups; 336 group = func->groups;
335 for_each_set_bit(bit, &mask_cpy, mask_len) { 337 for_each_set_bit(bit, &mask_cpy, mask_len) {
336 *group = pins[bit].name; 338 *group = pins[bit].name;
337 group++; 339 group++;
338 } 340 }
339 } 341 }
342
343 return 0;
340} 344}
341 345
342static void axp20x_build_funcs_groups(struct platform_device *pdev) 346static int axp20x_build_funcs_groups(struct platform_device *pdev)
343{ 347{
344 struct axp20x_pctl *pctl = platform_get_drvdata(pdev); 348 struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
345 int i, pin, npins = pctl->desc->npins; 349 int i, ret, pin, npins = pctl->desc->npins;
346 350
347 pctl->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out"; 351 pctl->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out";
348 pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT; 352 pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT;
@@ -366,13 +370,19 @@ static void axp20x_build_funcs_groups(struct platform_device *pdev)
366 pctl->funcs[i].groups[pin] = pctl->desc->pins[pin].name; 370 pctl->funcs[i].groups[pin] = pctl->desc->pins[pin].name;
367 } 371 }
368 372
369 axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->ldo_mask, 373 ret = axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->ldo_mask,
370 npins, &pctl->funcs[AXP20X_FUNC_LDO], 374 npins, &pctl->funcs[AXP20X_FUNC_LDO],
371 pctl->desc->pins); 375 pctl->desc->pins);
376 if (ret)
377 return ret;
372 378
373 axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->adc_mask, 379 ret = axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->adc_mask,
374 npins, &pctl->funcs[AXP20X_FUNC_ADC], 380 npins, &pctl->funcs[AXP20X_FUNC_ADC],
375 pctl->desc->pins); 381 pctl->desc->pins);
382 if (ret)
383 return ret;
384
385 return 0;
376} 386}
377 387
378static const struct of_device_id axp20x_pctl_match[] = { 388static const struct of_device_id axp20x_pctl_match[] = {
@@ -424,7 +434,11 @@ static int axp20x_pctl_probe(struct platform_device *pdev)
424 434
425 platform_set_drvdata(pdev, pctl); 435 platform_set_drvdata(pdev, pctl);
426 436
427 axp20x_build_funcs_groups(pdev); 437 ret = axp20x_build_funcs_groups(pdev);
438 if (ret) {
439 dev_err(&pdev->dev, "failed to build groups\n");
440 return ret;
441 }
428 442
429 pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctrl_desc), GFP_KERNEL); 443 pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctrl_desc), GFP_KERNEL);
430 if (!pctrl_desc) 444 if (!pctrl_desc)