Commit ba31c58d468aa22cc8b9ec0eb896b75a868e4bd1
Committed by
Greg Kroah-Hartman
1 parent
198bcce84a
regulator: core: fix race condition in regulator_put()
commit 83b0302d347a49f951e904184afe57ac3723476e upstream. The regulator framework maintains a list of consumer regulators for a regulator device and protects it from concurrent access using the regulator device's mutex lock. In the case of regulator_put() the consumer is removed and regulator device's parameters are updated without holding the regulator device's mutex. This would lead to a race condition between the regulator_put() and any function which traverses the consumer list or modifies regulator device's parameters. Fix this race condition by holding the regulator device's mutex in case of regulator_put. Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 3 additions and 1 deletions Side-by-side Diff
drivers/regulator/core.c
... | ... | @@ -1488,7 +1488,7 @@ |
1488 | 1488 | } |
1489 | 1489 | EXPORT_SYMBOL_GPL(regulator_get_optional); |
1490 | 1490 | |
1491 | -/* Locks held by regulator_put() */ | |
1491 | +/* regulator_list_mutex lock held by regulator_put() */ | |
1492 | 1492 | static void _regulator_put(struct regulator *regulator) |
1493 | 1493 | { |
1494 | 1494 | struct regulator_dev *rdev; |
1495 | 1495 | |
... | ... | @@ -1503,12 +1503,14 @@ |
1503 | 1503 | /* remove any sysfs entries */ |
1504 | 1504 | if (regulator->dev) |
1505 | 1505 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); |
1506 | + mutex_lock(&rdev->mutex); | |
1506 | 1507 | kfree(regulator->supply_name); |
1507 | 1508 | list_del(®ulator->list); |
1508 | 1509 | kfree(regulator); |
1509 | 1510 | |
1510 | 1511 | rdev->open_count--; |
1511 | 1512 | rdev->exclusive = 0; |
1513 | + mutex_unlock(&rdev->mutex); | |
1512 | 1514 | |
1513 | 1515 | module_put(rdev->owner); |
1514 | 1516 | } |