regulator: core: Fix slab-out-of-bounds in regulator_unlock_recursive()
commit0a7416f947
upstream. The recent commit7d8196641e
("regulator: Remove pointer table overallocation") changed the size of coupled_rdevs and now KASAN is able to detect slab-out-of-bounds problem in regulator_unlock_recursive(), which is a legit problem caused by a typo in the code. The recursive unlock function uses n_coupled value of a parent regulator for unlocking supply regulator, while supply's n_coupled should be used. In practice problem may only affect platforms that use coupled regulators. Cc: stable@vger.kernel.org # 5.0+ Fixes:f8702f9e4a
("regulator: core: Use ww_mutex for regulators locking") Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Link: https://lore.kernel.org/r/20200831204335.19489-1-digetx@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
dfbb9cea5a
commit
a467624aef
|
@ -235,8 +235,8 @@ static bool regulator_supply_is_couple(struct regulator_dev *rdev)
|
||||||
static void regulator_unlock_recursive(struct regulator_dev *rdev,
|
static void regulator_unlock_recursive(struct regulator_dev *rdev,
|
||||||
unsigned int n_coupled)
|
unsigned int n_coupled)
|
||||||
{
|
{
|
||||||
struct regulator_dev *c_rdev;
|
struct regulator_dev *c_rdev, *supply_rdev;
|
||||||
int i;
|
int i, supply_n_coupled;
|
||||||
|
|
||||||
for (i = n_coupled; i > 0; i--) {
|
for (i = n_coupled; i > 0; i--) {
|
||||||
c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1];
|
c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1];
|
||||||
|
@ -244,10 +244,13 @@ static void regulator_unlock_recursive(struct regulator_dev *rdev,
|
||||||
if (!c_rdev)
|
if (!c_rdev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev))
|
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) {
|
||||||
regulator_unlock_recursive(
|
supply_rdev = c_rdev->supply->rdev;
|
||||||
c_rdev->supply->rdev,
|
supply_n_coupled = supply_rdev->coupling_desc.n_coupled;
|
||||||
c_rdev->coupling_desc.n_coupled);
|
|
||||||
|
regulator_unlock_recursive(supply_rdev,
|
||||||
|
supply_n_coupled);
|
||||||
|
}
|
||||||
|
|
||||||
regulator_unlock(c_rdev);
|
regulator_unlock(c_rdev);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue