aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulia Lawall <julia.lawall@lip6.fr>2013-01-06 15:46:23 -0500
committerAnton Vorontsov <anton@enomsg.org>2013-01-06 15:46:23 -0500
commit0853699252afdeece69c9127d57fd367d3c04a35 (patch)
tree591115b3f18593cf52f358ac52960a6e48a50182
parent8feffd109977c045669913f4e80e8811f2212cd9 (diff)
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: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Anton Vorontsov <anton@enomsg.org>
-rw-r--r--drivers/power/88pm860x_battery.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c
index 8bc80b05c63c..d338c1c4e8c8 100644
--- a/drivers/power/88pm860x_battery.c
+++ b/drivers/power/88pm860x_battery.c
@@ -915,15 +915,13 @@ static int pm860x_battery_probe(struct platform_device *pdev)
915 info->irq_cc = platform_get_irq(pdev, 0); 915 info->irq_cc = platform_get_irq(pdev, 0);
916 if (info->irq_cc <= 0) { 916 if (info->irq_cc <= 0) {
917 dev_err(&pdev->dev, "No IRQ resource!\n"); 917 dev_err(&pdev->dev, "No IRQ resource!\n");
918 ret = -EINVAL; 918 return -EINVAL;
919 goto out;
920 } 919 }
921 920
922 info->irq_batt = platform_get_irq(pdev, 1); 921 info->irq_batt = platform_get_irq(pdev, 1);
923 if (info->irq_batt <= 0) { 922 if (info->irq_batt <= 0) {
924 dev_err(&pdev->dev, "No IRQ resource!\n"); 923 dev_err(&pdev->dev, "No IRQ resource!\n");
925 ret = -EINVAL; 924 return -EINVAL;
926 goto out;
927 } 925 }
928 926
929 info->chip = chip; 927 info->chip = chip;
@@ -957,7 +955,7 @@ static int pm860x_battery_probe(struct platform_device *pdev)
957 955
958 ret = power_supply_register(&pdev->dev, &info->battery); 956 ret = power_supply_register(&pdev->dev, &info->battery);
959 if (ret) 957 if (ret)
960 goto out; 958 return ret;
961 info->battery.dev->parent = &pdev->dev; 959 info->battery.dev->parent = &pdev->dev;
962 960
963 ret = request_threaded_irq(info->irq_cc, NULL, 961 ret = request_threaded_irq(info->irq_cc, NULL,
@@ -984,8 +982,6 @@ out_coulomb:
984 free_irq(info->irq_cc, info); 982 free_irq(info->irq_cc, info);
985out_reg: 983out_reg:
986 power_supply_unregister(&info->battery); 984 power_supply_unregister(&info->battery);
987out:
988 kfree(info);
989 return ret; 985 return ret;
990} 986}
991 987
@@ -993,10 +989,9 @@ static int pm860x_battery_remove(struct platform_device *pdev)
993{ 989{
994 struct pm860x_battery_info *info = platform_get_drvdata(pdev); 990 struct pm860x_battery_info *info = platform_get_drvdata(pdev);
995 991
996 power_supply_unregister(&info->battery);
997 free_irq(info->irq_batt, info); 992 free_irq(info->irq_batt, info);
998 free_irq(info->irq_cc, info); 993 free_irq(info->irq_cc, info);
999 kfree(info); 994 power_supply_unregister(&info->battery);
1000 platform_set_drvdata(pdev, NULL); 995 platform_set_drvdata(pdev, NULL);
1001 return 0; 996 return 0;
1002} 997}