Skip to content

Commit 093d27b

Browse files
DorianRudolphsre
authored andcommitted
power: supply: core: Fix boundary conditions in interpolation
The functions power_supply_temp2resist_simple and power_supply_ocv2cap_simple handle boundary conditions incorrectly. The change was introduced in a4585ba ("power: supply: core: Use library interpolation"). There are two issues: First, the lines "high = i - 1" and "high = i" in ocv2cap have the wrong order compared to temp2resist. As a consequence, ocv2cap sets high=-1 if ocv>table[0].ocv, which causes an out-of-bounds read. Second, the logic of temp2resist is also not correct. Consider the case table[] = {{20, 100}, {10, 80}, {0, 60}}. For temp=5, we expect a resistance of 70% by interpolation. However, temp2resist sets high=low=2 and returns 60. Cc: stable@vger.kernel.org Signed-off-by: Dorian Rudolph <mail@dorianrudolph.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Fixes: a4585ba ("power: supply: core: Use library interpolation") Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
1 parent 80192ef commit 093d27b

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

drivers/power/supply/power_supply_core.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -846,17 +846,17 @@ int power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *t
846846
{
847847
int i, high, low;
848848

849-
/* Break loop at table_len - 1 because that is the highest index */
850-
for (i = 0; i < table_len - 1; i++)
849+
for (i = 0; i < table_len; i++)
851850
if (temp > table[i].temp)
852851
break;
853852

854853
/* The library function will deal with high == low */
855-
if ((i == 0) || (i == (table_len - 1)))
856-
high = i;
854+
if (i == 0)
855+
high = low = i;
856+
else if (i == table_len)
857+
high = low = i - 1;
857858
else
858-
high = i - 1;
859-
low = i;
859+
high = (low = i) - 1;
860860

861861
return fixp_linear_interpolate(table[low].temp,
862862
table[low].resistance,
@@ -958,17 +958,17 @@ int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_table *table,
958958
{
959959
int i, high, low;
960960

961-
/* Break loop at table_len - 1 because that is the highest index */
962-
for (i = 0; i < table_len - 1; i++)
961+
for (i = 0; i < table_len; i++)
963962
if (ocv > table[i].ocv)
964963
break;
965964

966965
/* The library function will deal with high == low */
967-
if ((i == 0) || (i == (table_len - 1)))
968-
high = i - 1;
966+
if (i == 0)
967+
high = low = i;
968+
else if (i == table_len)
969+
high = low = i - 1;
969970
else
970-
high = i; /* i.e. i == 0 */
971-
low = i;
971+
high = (low = i) - 1;
972972

973973
return fixp_linear_interpolate(table[low].ocv,
974974
table[low].capacity,

0 commit comments

Comments
 (0)