linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] regulator: core: avoid memory access after freeing it
@ 2012-11-06 10:34 Laxman Dewangan
  2012-11-06 11:12 ` Charles Keepax
  0 siblings, 1 reply; 8+ messages in thread
From: Laxman Dewangan @ 2012-11-06 10:34 UTC (permalink / raw)
  To: broonie, lrg; +Cc: linux-kernel, Laxman Dewangan, Charles Keepax

When regulator_register() failed due to non availability of
supply then it exits through cleanup path. In this case it
checks for supply and if it is valid then unregister the supply.

The change done by Charles Keepax:
	regulator: core: Move regulator release to avoid deadlock

puts the release of supply regualtor after device_unregister().
The device_unregister() frees the rdev and hence accessing rdev
member pointer after this calls gives incorrect pointer and cause
the system to crash.

Adding the locked version of regulator_put() as __regulator_put_locked()
so that it can be called in locked context also to avoid the deadlock
to address the above issue.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/regulator/core.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index b4a425a..59280b6 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1382,23 +1382,16 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
 EXPORT_SYMBOL_GPL(regulator_get_exclusive);
 
 /**
- * regulator_put - "free" the regulator source
- * @regulator: regulator source
- *
- * Note: drivers must ensure that all regulator_enable calls made on this
- * regulator source are balanced by regulator_disable calls prior to calling
- * this function.
+ * Locked version of regulator_put
  */
-void regulator_put(struct regulator *regulator)
+static void __regulator_put_locked(struct regulator *regulator)
 {
 	struct regulator_dev *rdev;
 
 	if (regulator == NULL || IS_ERR(regulator))
 		return;
 
-	mutex_lock(&regulator_list_mutex);
 	rdev = regulator->rdev;
-
 	debugfs_remove_recursive(regulator->debugfs);
 
 	/* remove any sysfs entries */
@@ -1412,6 +1405,20 @@ void regulator_put(struct regulator *regulator)
 	rdev->exclusive = 0;
 
 	module_put(rdev->owner);
+}
+
+/**
+ * regulator_put - "free" the regulator source
+ * @regulator: regulator source
+ *
+ * Note: drivers must ensure that all regulator_enable calls made on this
+ * regulator source are balanced by regulator_disable calls prior to calling
+ * this function.
+ */
+void regulator_put(struct regulator *regulator)
+{
+	mutex_lock(&regulator_list_mutex);
+	__regulator_put_locked(regulator);
 	mutex_unlock(&regulator_list_mutex);
 }
 EXPORT_SYMBOL_GPL(regulator_put);
@@ -3453,11 +3460,10 @@ scrub:
 		gpio_free(rdev->ena_gpio);
 	kfree(rdev->constraints);
 wash:
+	if (rdev->supply)
+		__regulator_put_locked(rdev->supply);
 	device_unregister(&rdev->dev);
-
 	mutex_unlock(&regulator_list_mutex);
-	if (rdev->supply)
-		regulator_put(rdev->supply);
 
 	/* device core frees rdev */
 	rdev = ERR_PTR(ret);
-- 
1.7.1.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-11-14 10:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-06 10:34 [PATCH] regulator: core: avoid memory access after freeing it Laxman Dewangan
2012-11-06 11:12 ` Charles Keepax
2012-11-06 11:31   ` Mark Brown
2012-11-13 16:30     ` [PATCH] regulator: core: Add locked version of regulator_put to avoid deadlock Charles Keepax
2012-11-13 17:16       ` Laxman Dewangan
2012-11-13 23:25       ` Mark Brown
2012-11-14  9:39         ` [PATCH v2] regulator: core: Avoid deadlock when regulator_register fails Charles Keepax
2012-11-14 10:01           ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).