Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08536992 authored by Julia Lawall's avatar Julia Lawall Committed by Anton Vorontsov
Browse files

88pm860x_battery: Eliminate possible references to released resources

devm_kzalloc should not be followed by kfree, as this results in a double
free.  The problem was found using the following semantic match
(http://coccinelle.lip6.fr/

):

// <smpl>
@@
expression x,e;
@@
x = devm_kzalloc(...)
... when != x = e
?-kfree(x,...);
// </smpl>

Furthermore, in the remove function, the calls to free_irq are moved up to
prevent a possible reference in the interrupt handler to resources freed by
power_supply_unregister.

Signed-off-by: default avatarJulia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: default avatarAnton Vorontsov <anton@enomsg.org>
parent 8feffd10
Loading
Loading
Loading
Loading
+4 −9
Original line number Diff line number Diff line
@@ -915,15 +915,13 @@ static int pm860x_battery_probe(struct platform_device *pdev)
	info->irq_cc = platform_get_irq(pdev, 0);
	if (info->irq_cc <= 0) {
		dev_err(&pdev->dev, "No IRQ resource!\n");
		ret = -EINVAL;
		goto out;
		return -EINVAL;
	}

	info->irq_batt = platform_get_irq(pdev, 1);
	if (info->irq_batt <= 0) {
		dev_err(&pdev->dev, "No IRQ resource!\n");
		ret = -EINVAL;
		goto out;
		return -EINVAL;
	}

	info->chip = chip;
@@ -957,7 +955,7 @@ static int pm860x_battery_probe(struct platform_device *pdev)

	ret = power_supply_register(&pdev->dev, &info->battery);
	if (ret)
		goto out;
		return ret;
	info->battery.dev->parent = &pdev->dev;

	ret = request_threaded_irq(info->irq_cc, NULL,
@@ -984,8 +982,6 @@ static int pm860x_battery_probe(struct platform_device *pdev)
	free_irq(info->irq_cc, info);
out_reg:
	power_supply_unregister(&info->battery);
out:
	kfree(info);
	return ret;
}

@@ -993,10 +989,9 @@ static int pm860x_battery_remove(struct platform_device *pdev)
{
	struct pm860x_battery_info *info = platform_get_drvdata(pdev);

	power_supply_unregister(&info->battery);
	free_irq(info->irq_batt, info);
	free_irq(info->irq_cc, info);
	kfree(info);
	power_supply_unregister(&info->battery);
	platform_set_drvdata(pdev, NULL);
	return 0;
}