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

regulator: ti-abb: Fix array out of bound read access on the first transition

At the start of driver initialization, we do not know what bias
setting the bootloader has configured the system for and we only know
for certain the very first time we do a transition.

However, since the initial value of the comparison index is -EINVAL,
this negative value results in an array out of bound access on the
very first transition.

Since we don't know what the setting is, we just set the bias
configuration as there is nothing to compare against. This prevents
the array out of bound access.

NOTE: Even though we could use a more relaxed check of "< 0" the only
valid values(ignoring cosmic ray induced bitflips) are -EINVAL, 0+.

Fixes: 40b1936efebd ("regulator: Introduce TI Adaptive Body Bias(ABB) on-chip LDO driver")
Link: https://lore.kernel.org/linux-mm/CA+G9fYuk4imvhyCN7D7T6PMDH6oNp6HDCRiTUKMQ6QXXjBa4ag@mail.gmail.com/
Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Nishanth Menon <nm@ti.com>
Link: https://lore.kernel.org/r/20201118145009.10492-1-nm@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Nishanth Menon and committed by
Mark Brown
2ba546eb f5c042b2

+11 -1
+11 -1
drivers/regulator/ti-abb-regulator.c
··· 342 342 return ret; 343 343 } 344 344 345 - /* If data is exactly the same, then just update index, no change */ 346 345 info = &abb->info[sel]; 346 + /* 347 + * When Linux kernel is starting up, we are'nt sure of the 348 + * Bias configuration that bootloader has configured. 349 + * So, we get to know the actual setting the first time 350 + * we are asked to transition. 351 + */ 352 + if (abb->current_info_idx == -EINVAL) 353 + goto just_set_abb; 354 + 355 + /* If data is exactly the same, then just update index, no change */ 347 356 oinfo = &abb->info[abb->current_info_idx]; 348 357 if (!memcmp(info, oinfo, sizeof(*info))) { 349 358 dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n", __func__, ··· 360 351 goto out; 361 352 } 362 353 354 + just_set_abb: 363 355 ret = ti_abb_set_opp(rdev, abb, info); 364 356 365 357 out: