aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@gmail.com>2011-07-10 21:57:43 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2011-07-22 06:41:57 -0400
commit39aa9b6e3cb1b2a564d3422eedb7f725179162d3 (patch)
tree4c4ab6357e1d422971212504d8cb3d441ca8d638 /drivers/regulator
parentd04156bca629740a661fd0738cd69ba1f08b2b20 (diff)
regulator: tps65910: Fix array access out of bounds bug
For tps65910, the number of regulator is 13. ( ARRAY_SIZE(tps65910_regs) is 13) For tps65911, the number of regulator is 12. ( ARRAY_SIZE(tps65911_regs) is 12) If we are using this driver for tps65911, we hit array access out of bounds bug in tps65910_probe() because current implementation always assume the number of regulator is 13 and thus it will access tps65911_regs[12]. Fix it by setting correct num_regulators for both chips in tps65910_probe(), and allocated neccessay memory accordingly. Signed-off-by: Axel Lin <axel.lin@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/tps65910-regulator.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 8e0edab74786..66d2d60b436a 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -49,7 +49,6 @@
49#define TPS65911_REG_LDO7 11 49#define TPS65911_REG_LDO7 11
50#define TPS65911_REG_LDO8 12 50#define TPS65911_REG_LDO8 12
51 51
52#define TPS65910_NUM_REGULATOR 13
53#define TPS65910_SUPPLY_STATE_ENABLED 0x1 52#define TPS65910_SUPPLY_STATE_ENABLED 0x1
54 53
55/* supported VIO voltages in milivolts */ 54/* supported VIO voltages in milivolts */
@@ -264,11 +263,12 @@ static struct tps_info tps65911_regs[] = {
264}; 263};
265 264
266struct tps65910_reg { 265struct tps65910_reg {
267 struct regulator_desc desc[TPS65910_NUM_REGULATOR]; 266 struct regulator_desc *desc;
268 struct tps65910 *mfd; 267 struct tps65910 *mfd;
269 struct regulator_dev *rdev[TPS65910_NUM_REGULATOR]; 268 struct regulator_dev **rdev;
270 struct tps_info *info[TPS65910_NUM_REGULATOR]; 269 struct tps_info **info;
271 struct mutex mutex; 270 struct mutex mutex;
271 int num_regulators;
272 int mode; 272 int mode;
273 int (*get_ctrl_reg)(int); 273 int (*get_ctrl_reg)(int);
274}; 274};
@@ -902,10 +902,12 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
902 switch(tps65910_chip_id(tps65910)) { 902 switch(tps65910_chip_id(tps65910)) {
903 case TPS65910: 903 case TPS65910:
904 pmic->get_ctrl_reg = &tps65910_get_ctrl_register; 904 pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
905 pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
905 info = tps65910_regs; 906 info = tps65910_regs;
906 break; 907 break;
907 case TPS65911: 908 case TPS65911:
908 pmic->get_ctrl_reg = &tps65911_get_ctrl_register; 909 pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
910 pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
909 info = tps65911_regs; 911 info = tps65911_regs;
910 break; 912 break;
911 default: 913 default:
@@ -914,7 +916,28 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
914 return -ENODEV; 916 return -ENODEV;
915 } 917 }
916 918
917 for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { 919 pmic->desc = kcalloc(pmic->num_regulators,
920 sizeof(struct regulator_desc), GFP_KERNEL);
921 if (!pmic->desc) {
922 err = -ENOMEM;
923 goto err_free_pmic;
924 }
925
926 pmic->info = kcalloc(pmic->num_regulators,
927 sizeof(struct tps_info *), GFP_KERNEL);
928 if (!pmic->info) {
929 err = -ENOMEM;
930 goto err_free_desc;
931 }
932
933 pmic->rdev = kcalloc(pmic->num_regulators,
934 sizeof(struct regulator_dev *), GFP_KERNEL);
935 if (!pmic->rdev) {
936 err = -ENOMEM;
937 goto err_free_info;
938 }
939
940 for (i = 0; i < pmic->num_regulators; i++, info++, reg_data++) {
918 /* Register the regulators */ 941 /* Register the regulators */
919 pmic->info[i] = info; 942 pmic->info[i] = info;
920 943
@@ -946,7 +969,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
946 "failed to register %s regulator\n", 969 "failed to register %s regulator\n",
947 pdev->name); 970 pdev->name);
948 err = PTR_ERR(rdev); 971 err = PTR_ERR(rdev);
949 goto err; 972 goto err_unregister_regulator;
950 } 973 }
951 974
952 /* Save regulator for cleanup */ 975 /* Save regulator for cleanup */
@@ -954,23 +977,31 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
954 } 977 }
955 return 0; 978 return 0;
956 979
957err: 980err_unregister_regulator:
958 while (--i >= 0) 981 while (--i >= 0)
959 regulator_unregister(pmic->rdev[i]); 982 regulator_unregister(pmic->rdev[i]);
960 983 kfree(pmic->rdev);
984err_free_info:
985 kfree(pmic->info);
986err_free_desc:
987 kfree(pmic->desc);
988err_free_pmic:
961 kfree(pmic); 989 kfree(pmic);
962 return err; 990 return err;
963} 991}
964 992
965static int __devexit tps65910_remove(struct platform_device *pdev) 993static int __devexit tps65910_remove(struct platform_device *pdev)
966{ 994{
967 struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev); 995 struct tps65910_reg *pmic = platform_get_drvdata(pdev);
968 int i; 996 int i;
969 997
970 for (i = 0; i < TPS65910_NUM_REGULATOR; i++) 998 for (i = 0; i < pmic->num_regulators; i++)
971 regulator_unregister(tps65910_reg->rdev[i]); 999 regulator_unregister(pmic->rdev[i]);
972 1000
973 kfree(tps65910_reg); 1001 kfree(pmic->rdev);
1002 kfree(pmic->info);
1003 kfree(pmic->desc);
1004 kfree(pmic);
974 return 0; 1005 return 0;
975} 1006}
976 1007