Commit 7ee1a01e authored by Baruch Siach's avatar Baruch Siach Committed by Bartosz Golaszewski

gpio: mvebu: fix potential user-after-free on probe

When mvebu_pwm_probe() fails IRQ domain is not released. Move pwm probe
before IRQ domain allocation. Add pwm cleanup code to the failure path.

Fixes: 757642f9 ("gpio: mvebu: Add limited PWM support")
Reported-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarBaruch Siach <baruch@tkos.co.il>
Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
parent 7f57b295
...@@ -1197,6 +1197,13 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1197,6 +1197,13 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip);
/* Some MVEBU SoCs have simple PWM support for GPIO lines */
if (IS_ENABLED(CONFIG_PWM)) {
err = mvebu_pwm_probe(pdev, mvchip, id);
if (err)
return err;
}
/* Some gpio controllers do not provide irq support */ /* Some gpio controllers do not provide irq support */
if (!have_irqs) if (!have_irqs)
return 0; return 0;
...@@ -1206,7 +1213,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1206,7 +1213,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
if (!mvchip->domain) { if (!mvchip->domain) {
dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
mvchip->chip.label); mvchip->chip.label);
return -ENODEV; err = -ENODEV;
goto err_pwm;
} }
err = irq_alloc_domain_generic_chips( err = irq_alloc_domain_generic_chips(
...@@ -1254,14 +1262,12 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1254,14 +1262,12 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
mvchip); mvchip);
} }
/* Some MVEBU SoCs have simple PWM support for GPIO lines */
if (IS_ENABLED(CONFIG_PWM))
return mvebu_pwm_probe(pdev, mvchip, id);
return 0; return 0;
err_domain: err_domain:
irq_domain_remove(mvchip->domain); irq_domain_remove(mvchip->domain);
err_pwm:
pwmchip_remove(&mvchip->mvpwm->chip);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment