power: supply: bq25980: Fix uninitialized wd_reg_val and overrun
authorDan Murphy <dmurphy@ti.com>
Fri, 9 Oct 2020 12:12:05 +0000 (07:12 -0500)
committerSebastian Reichel <sre@kernel.org>
Tue, 13 Oct 2020 21:24:10 +0000 (23:24 +0200)
Fix the issue when 'i' is equal to array size then array index over
runs the array when checking for the watch dog value.

Fixes: 5069185fc18e ("power: supply: bq25980: Add support for the BQ259xx family")
Signed-off-by: Dan Murphy <dmurphy@ti.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/supply/bq25980_charger.c

index db69ec412a679299ac435b1d6e3d9791925ae76c..c936f311eb4f0e53e48aec7bf69f7ab35d5d7be4 100644 (file)
@@ -1096,28 +1096,29 @@ static int bq25980_power_supply_init(struct bq25980_device *bq,
 static int bq25980_hw_init(struct bq25980_device *bq)
 {
        struct power_supply_battery_info bat_info = { };
-       int wd_reg_val = 0;
+       int wd_reg_val = BQ25980_WATCHDOG_DIS;
+       int wd_max_val = BQ25980_NUM_WD_VAL - 1;
        int ret = 0;
        int curr_val;
        int volt_val;
        int i;
 
-       if (!bq->watchdog_timer) {
-               ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3,
-                                        BQ25980_WATCHDOG_DIS,
-                                        BQ25980_WATCHDOG_DIS);
-       } else {
-               for (i = 0; i < BQ25980_NUM_WD_VAL; i++) {
-                       if (bq->watchdog_timer > bq25980_watchdog_time[i] &&
-                           bq->watchdog_timer < bq25980_watchdog_time[i + 1]) {
-                               wd_reg_val = i;
-                               break;
+       if (bq->watchdog_timer) {
+               if (bq->watchdog_timer >= bq25980_watchdog_time[wd_max_val])
+                       wd_reg_val = wd_max_val;
+               else {
+                       for (i = 0; i < wd_max_val; i++) {
+                               if (bq->watchdog_timer > bq25980_watchdog_time[i] &&
+                                   bq->watchdog_timer < bq25980_watchdog_time[i + 1]) {
+                                       wd_reg_val = i;
+                                       break;
+                               }
                        }
                }
-
-               ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3,
-                                       BQ25980_WATCHDOG_MASK, wd_reg_val);
        }
+
+       ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3,
+                                BQ25980_WATCHDOG_MASK, wd_reg_val);
        if (ret)
                return ret;