Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 a4585ba2050f460f749bbaf2b67bd56c41e30283
("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: a4585ba2050f ("power: supply: core: Use library interpolation")
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Dorian Rudolph and committed by
Sebastian Reichel
093d27bb 80192eff

+12 -12
+12 -12
drivers/power/supply/power_supply_core.c
··· 846 846 { 847 847 int i, high, low; 848 848 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++) 851 850 if (temp > table[i].temp) 852 851 break; 853 852 854 853 /* 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; 857 858 else 858 - high = i - 1; 859 - low = i; 859 + high = (low = i) - 1; 860 860 861 861 return fixp_linear_interpolate(table[low].temp, 862 862 table[low].resistance, ··· 958 958 { 959 959 int i, high, low; 960 960 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++) 963 962 if (ocv > table[i].ocv) 964 963 break; 965 964 966 965 /* 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; 969 970 else 970 - high = i; /* i.e. i == 0 */ 971 - low = i; 971 + high = (low = i) - 1; 972 972 973 973 return fixp_linear_interpolate(table[low].ocv, 974 974 table[low].capacity,