linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] regulator: core: fix race condition in regulator_put()
@ 2015-01-07 13:51 Ashay Jaiswal
  2015-01-07 17:06 ` Mark Brown
  0 siblings, 1 reply; 3+ messages in thread
From: Ashay Jaiswal @ 2015-01-07 13:51 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown
  Cc: linux-kernel, linux-arm-msm, Anirudh Ghayal, Ashay Jaiswal

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 without
holding the regulator device's mutex, resulting in a race condition
between any regulator operation which traverses the consumer list
and regulator_put() which releases the consumer regulator.
Fix this race condition by holding the regulator device's mutex while
removing and releasing the consumer regulator.

Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
---
 drivers/regulator/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c2554d8..3845397 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1498,6 +1498,7 @@ static void _regulator_put(struct regulator *regulator)

 	rdev = regulator->rdev;

+	mutex_lock(&rdev->mutex);
 	debugfs_remove_recursive(regulator->debugfs);

 	/* remove any sysfs entries */
@@ -1511,6 +1512,7 @@ static void _regulator_put(struct regulator *regulator)
 	rdev->exclusive = 0;

 	module_put(rdev->owner);
+	mutex_unlock(&rdev->mutex);
 }

 /**
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH] regulator: core: fix race condition in regulator_put()
  2015-01-07 13:51 [PATCH] regulator: core: fix race condition in regulator_put() Ashay Jaiswal
@ 2015-01-07 17:06 ` Mark Brown
  2015-01-08 12:58   ` ashayj
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Brown @ 2015-01-07 17:06 UTC (permalink / raw)
  To: Ashay Jaiswal; +Cc: Liam Girdwood, linux-kernel, linux-arm-msm, Anirudh Ghayal

[-- Attachment #1: Type: text/plain, Size: 1569 bytes --]

On Wed, Jan 07, 2015 at 07:21:23PM +0530, Ashay Jaiswal wrote:

> 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 without
> holding the regulator device's mutex, resulting in a race condition
> between any regulator operation which traverses the consumer list
> and regulator_put() which releases the consumer regulator.
> Fix this race condition by holding the regulator device's mutex while
> removing and releasing the consumer regulator.

This is a good spot thanks but I think your analysis here is missing a
bit - it's not just the list manipulation that affects the rdev, it's
also the reference count in the rdev and the exclusive flag.  Indeed
some of this issue applies on the _get() side too, while we do add the
regulator to the list under the rdev mutex we don't have the mutex when
we update the reference count meaning that we've got a potential issue
with that.  That *is* kind of separate though so could be dealt with in
a separate patch.

The lock region also seems too wide, the lock is only needed for the
operations that affect the rdev not for the operations only on the
object being freed - holding the lock for too long means impacting other
users and some of the cleanup is potentially expensive.  The comment at
the top of the function needs updating too, it currently says that the
lock is held in the caller but this applies only to the regulator_list_mutex.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [PATCH] regulator: core: fix race condition in regulator_put()
  2015-01-07 17:06 ` Mark Brown
@ 2015-01-08 12:58   ` ashayj
  0 siblings, 0 replies; 3+ messages in thread
From: ashayj @ 2015-01-08 12:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: Ashay Jaiswal, Liam Girdwood, linux-kernel, linux-arm-msm,
	Anirudh Ghayal, David Collins

Thanks Mark for your review comments.

> On Wed, Jan 07, 2015 at 07:21:23PM +0530, Ashay Jaiswal wrote:
>
>> 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 without
>> holding the regulator device's mutex, resulting in a race condition
>> between any regulator operation which traverses the consumer list
>> and regulator_put() which releases the consumer regulator.
>> Fix this race condition by holding the regulator device's mutex while
>> removing and releasing the consumer regulator.
>
> This is a good spot thanks but I think your analysis here is missing a
> bit - it's not just the list manipulation that affects the rdev, it's
> also the reference count in the rdev and the exclusive flag.  Indeed
> some of this issue applies on the _get() side too, while we do add the
> regulator to the list under the rdev mutex we don't have the mutex when
> we update the reference count meaning that we've got a potential issue
> with that.  That *is* kind of separate though so could be dealt with in
> a separate patch.
>

I have updated the commit message as per your suggestion.
I will try to fix the regulator_get path.

> The lock region also seems too wide, the lock is only needed for the
> operations that affect the rdev not for the operations only on the
> object being freed - holding the lock for too long means impacting other
> users and some of the cleanup is potentially expensive.  The comment at
> the top of the function needs updating too, it currently says that the
> lock is held in the caller but this applies only to the
> regulator_list_mutex.
>
Yes I too agree with your suggestion, updated the lock region to protect
only rdev parameters.
Also updated the comment on top of the _regulator_put function to reflect
regulator_list_mutex lock is held by caller.

I will upload next version of patch incorporating all the review comments.

Ashay Jaiswal



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

end of thread, other threads:[~2015-01-08 12:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-07 13:51 [PATCH] regulator: core: fix race condition in regulator_put() Ashay Jaiswal
2015-01-07 17:06 ` Mark Brown
2015-01-08 12:58   ` ashayj

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).