All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] of: Deep-copy names of platform devices
@ 2014-08-13  0:57 Stepan Moskovchenko
  2014-08-13  1:46 ` Stephen Boyd
  0 siblings, 1 reply; 13+ messages in thread
From: Stepan Moskovchenko @ 2014-08-13  0:57 UTC (permalink / raw)
  To: grant.likely, robh+dt, devicetree; +Cc: linux-kernel, linux-arm-msm, stepanm

When we parse the device tree and allocate platform
devices, the 'name' of the newly-created platform_device
is set to point to the 'name' field of the 'struct device'
embedded within the platform_device. This is dangerous,
because the name of the 'struct device' is dynamically
allocated. Drivers may call dev_set_name() on the device,
which will free and reallocate the name of the device,
leaving the 'name' of the platform_device pointing to the
now-freed memory.

Furthermore, if the dev_set_name() call is made from a
driver's probe() function and a subsequent request results
in probe deferral, the dangling 'name' reference may lead
to the device being re-probed using the wrong driver.

To mitigate these scenarios, we use kstrdup to perform a
deep copy of the device name when assigning the name of the
platform_device, so that the platform_device name is
unaffected by any calls to dev_set_name() that might made
by drivers to rename the embedded 'struct device'.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
This is technically a 'v2' patch, but it looks like I used
an old version of MAINTAINERS, so I'll just re-send this
as a new patch to avoid confusion for people who missed the
original.

I suppose creating a 'pdev_set_name' API may seem like
another possibility, but I feel that dev.name and pdev.name
have two different meanings. One is used for device/driver
binding purposes, whereas the other serves a more general
identification purpose, and is used for things like sysfs.
Drivers might want to change dev.name while leaving the
pdev.name alone. I guess yet another possibility would be
to prohibit calling dev_set_name() on devices created from
device tree, but a driver does not necessarily know how a
given platform_device was allocated.

Steve

 drivers/of/device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index f685e55..3e116f6 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)

 	/* name and id have to be set so that the platform bus doesn't get
 	 * confused on matching */
-	ofdev->name = dev_name(&ofdev->dev);
+	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
 	ofdev->id = -1;

 	/* device_add will assume that this device is on the same node as
@@ -76,6 +76,7 @@ EXPORT_SYMBOL(of_device_register);
 void of_device_unregister(struct platform_device *ofdev)
 {
 	device_unregister(&ofdev->dev);
+	kfree(ofdev->name);
 }
 EXPORT_SYMBOL(of_device_unregister);

--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH] of: Deep-copy names of platform devices
  2014-08-13  0:57 [PATCH] of: Deep-copy names of platform devices Stepan Moskovchenko
@ 2014-08-13  1:46 ` Stephen Boyd
  2014-08-13  2:30   ` [PATCH v2] " Stepan Moskovchenko
  2014-08-15 10:45   ` [PATCH] " Grant Likely
  0 siblings, 2 replies; 13+ messages in thread
From: Stephen Boyd @ 2014-08-13  1:46 UTC (permalink / raw)
  To: Stepan Moskovchenko
  Cc: grant.likely, robh+dt, devicetree, linux-kernel, linux-arm-msm

On 08/12/14 17:57, Stepan Moskovchenko wrote:
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index f685e55..3e116f6 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>
>  	/* name and id have to be set so that the platform bus doesn't get
>  	 * confused on matching */
> -	ofdev->name = dev_name(&ofdev->dev);
> +	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>  	ofdev->id = -1;
>
>  	/* device_add will assume that this device is on the same node as
> @@ -76,6 +76,7 @@ EXPORT_SYMBOL(of_device_register);
>  void of_device_unregister(struct platform_device *ofdev)
>  {
>  	device_unregister(&ofdev->dev);
> +	kfree(ofdev->name);

This probably ought to be swapped because we don't know if ofdev isn't
pointing to freed memory after device_unregister().

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2] of: Deep-copy names of platform devices
  2014-08-13  1:46 ` Stephen Boyd
@ 2014-08-13  2:30   ` Stepan Moskovchenko
  2014-08-15 16:38     ` Rob Herring
  2014-08-15 10:45   ` [PATCH] " Grant Likely
  1 sibling, 1 reply; 13+ messages in thread
From: Stepan Moskovchenko @ 2014-08-13  2:30 UTC (permalink / raw)
  To: grant.likely, robh+dt, devicetree; +Cc: linux-kernel, linux-arm-msm, stepanm

When we parse the device tree and allocate platform
devices, the 'name' of the newly-created platform_device
is set to point to the 'name' field of the 'struct device'
embedded within the platform_device. This is dangerous,
because the name of the 'struct device' is dynamically
allocated. Drivers may call dev_set_name() on the device,
which will free and reallocate the name of the device,
leaving the 'name' of the platform_device pointing to the
now-freed memory.

Furthermore, if the dev_set_name() call is made from a
driver's probe() function and a subsequent request results
in probe deferral, the dangling 'name' reference may lead
to the device being re-probed using the wrong driver.

To mitigate these scenarios, we use kstrdup to perform a
deep copy of the device name when assigning the name of the
platform_device, so that the platform_device name is
unaffected by any calls to dev_set_name() that might made
by drivers to rename the embedded 'struct device'.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
* v2 - swap cleanup order

 drivers/of/device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index f685e55..e9beae6 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)

 	/* name and id have to be set so that the platform bus doesn't get
 	 * confused on matching */
-	ofdev->name = dev_name(&ofdev->dev);
+	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
 	ofdev->id = -1;

 	/* device_add will assume that this device is on the same node as
@@ -75,6 +75,7 @@ EXPORT_SYMBOL(of_device_register);

 void of_device_unregister(struct platform_device *ofdev)
 {
+	kfree(ofdev->name);
 	device_unregister(&ofdev->dev);
 }
 EXPORT_SYMBOL(of_device_unregister);
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH] of: Deep-copy names of platform devices
  2014-08-13  1:46 ` Stephen Boyd
  2014-08-13  2:30   ` [PATCH v2] " Stepan Moskovchenko
@ 2014-08-15 10:45   ` Grant Likely
  2014-08-15 10:52     ` Grant Likely
  1 sibling, 1 reply; 13+ messages in thread
From: Grant Likely @ 2014-08-15 10:45 UTC (permalink / raw)
  To: Stephen Boyd, Stepan Moskovchenko
  Cc: robh+dt, devicetree, linux-kernel, linux-arm-msm

On Tue, 12 Aug 2014 18:46:36 -0700, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 08/12/14 17:57, Stepan Moskovchenko wrote:
> > diff --git a/drivers/of/device.c b/drivers/of/device.c
> > index f685e55..3e116f6 100644
> > --- a/drivers/of/device.c
> > +++ b/drivers/of/device.c
> > @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
> >
> >  	/* name and id have to be set so that the platform bus doesn't get
> >  	 * confused on matching */
> > -	ofdev->name = dev_name(&ofdev->dev);
> > +	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
> >  	ofdev->id = -1;
> >
> >  	/* device_add will assume that this device is on the same node as
> > @@ -76,6 +76,7 @@ EXPORT_SYMBOL(of_device_register);
> >  void of_device_unregister(struct platform_device *ofdev)
> >  {
> >  	device_unregister(&ofdev->dev);
> > +	kfree(ofdev->name);
> 
> This probably ought to be swapped because we don't know if ofdev isn't
> pointing to freed memory after device_unregister().

Actually, the only safe place to free the memory is inside the
platform_device release function. platform_device_release() in
drivers/base/platform.c. Unfortunately there isn't a good way from that
function to figure out if the name has been allocated the 'OF' way.

It is not safe to free it here because there could still be references
to the platform_device after device_unregister exits.

g.

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

* Re: [PATCH] of: Deep-copy names of platform devices
  2014-08-15 10:45   ` [PATCH] " Grant Likely
@ 2014-08-15 10:52     ` Grant Likely
       [not found]       ` <CACxGe6tr_hX+XBD=C+y55OixrweVLZvNNFQHxSDHwuHbSYW-XQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Grant Likely @ 2014-08-15 10:52 UTC (permalink / raw)
  To: Stephen Boyd, Stepan Moskovchenko
  Cc: Rob Herring, devicetree, Linux Kernel Mailing List, linux-arm-msm

On Fri, Aug 15, 2014 at 11:45 AM, Grant Likely <grant.likely@linaro.org> wrote:
> On Tue, 12 Aug 2014 18:46:36 -0700, Stephen Boyd <sboyd@codeaurora.org> wrote:
>> On 08/12/14 17:57, Stepan Moskovchenko wrote:
>> > diff --git a/drivers/of/device.c b/drivers/of/device.c
>> > index f685e55..3e116f6 100644
>> > --- a/drivers/of/device.c
>> > +++ b/drivers/of/device.c
>> > @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>> >
>> >     /* name and id have to be set so that the platform bus doesn't get
>> >      * confused on matching */
>> > -   ofdev->name = dev_name(&ofdev->dev);
>> > +   ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>> >     ofdev->id = -1;
>> >
>> >     /* device_add will assume that this device is on the same node as
>> > @@ -76,6 +76,7 @@ EXPORT_SYMBOL(of_device_register);
>> >  void of_device_unregister(struct platform_device *ofdev)
>> >  {
>> >     device_unregister(&ofdev->dev);
>> > +   kfree(ofdev->name);
>>
>> This probably ought to be swapped because we don't know if ofdev isn't
>> pointing to freed memory after device_unregister().
>
> Actually, the only safe place to free the memory is inside the
> platform_device release function. platform_device_release() in
> drivers/base/platform.c. Unfortunately there isn't a good way from that
> function to figure out if the name has been allocated the 'OF' way.
>
> It is not safe to free it here because there could still be references
> to the platform_device after device_unregister exits.

We could fix the problem by making platform_device_alloc() also do a
kstrdup() when assigning the name. Then the release function can
unconditionally free the name field. Care to try that out?

g.

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

* Re: [PATCH] of: Deep-copy names of platform devices
  2014-08-15 10:52     ` Grant Likely
@ 2014-08-15 11:01           ` Grant Likely
  0 siblings, 0 replies; 13+ messages in thread
From: Grant Likely @ 2014-08-15 11:01 UTC (permalink / raw)
  To: Stephen Boyd, Stepan Moskovchenko
  Cc: Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Linux Kernel Mailing List, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA

On Fri, Aug 15, 2014 at 11:52 AM, Grant Likely <grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Aug 15, 2014 at 11:45 AM, Grant Likely <grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>> On Tue, 12 Aug 2014 18:46:36 -0700, Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
>>> On 08/12/14 17:57, Stepan Moskovchenko wrote:
>>> > diff --git a/drivers/of/device.c b/drivers/of/device.c
>>> > index f685e55..3e116f6 100644
>>> > --- a/drivers/of/device.c
>>> > +++ b/drivers/of/device.c
>>> > @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>>> >
>>> >     /* name and id have to be set so that the platform bus doesn't get
>>> >      * confused on matching */
>>> > -   ofdev->name = dev_name(&ofdev->dev);
>>> > +   ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>>> >     ofdev->id = -1;
>>> >
>>> >     /* device_add will assume that this device is on the same node as
>>> > @@ -76,6 +76,7 @@ EXPORT_SYMBOL(of_device_register);
>>> >  void of_device_unregister(struct platform_device *ofdev)
>>> >  {
>>> >     device_unregister(&ofdev->dev);
>>> > +   kfree(ofdev->name);
>>>
>>> This probably ought to be swapped because we don't know if ofdev isn't
>>> pointing to freed memory after device_unregister().
>>
>> Actually, the only safe place to free the memory is inside the
>> platform_device release function. platform_device_release() in
>> drivers/base/platform.c. Unfortunately there isn't a good way from that
>> function to figure out if the name has been allocated the 'OF' way.
>>
>> It is not safe to free it here because there could still be references
>> to the platform_device after device_unregister exits.
>
> We could fix the problem by making platform_device_alloc() also do a
> kstrdup() when assigning the name. Then the release function can
> unconditionally free the name field. Care to try that out?

I don't know how well received that will be though. The vast majority
of non-OF callers of platform_device_alloc() pass in a static string
that will never disappear.

Another possible solutions: Override the release function for platform
devices allocated by of_device_alloc() to free the name field.

g.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH] of: Deep-copy names of platform devices
@ 2014-08-15 11:01           ` Grant Likely
  0 siblings, 0 replies; 13+ messages in thread
From: Grant Likely @ 2014-08-15 11:01 UTC (permalink / raw)
  To: Stephen Boyd, Stepan Moskovchenko
  Cc: Rob Herring, devicetree, Linux Kernel Mailing List, linux-arm-msm

On Fri, Aug 15, 2014 at 11:52 AM, Grant Likely <grant.likely@linaro.org> wrote:
> On Fri, Aug 15, 2014 at 11:45 AM, Grant Likely <grant.likely@linaro.org> wrote:
>> On Tue, 12 Aug 2014 18:46:36 -0700, Stephen Boyd <sboyd@codeaurora.org> wrote:
>>> On 08/12/14 17:57, Stepan Moskovchenko wrote:
>>> > diff --git a/drivers/of/device.c b/drivers/of/device.c
>>> > index f685e55..3e116f6 100644
>>> > --- a/drivers/of/device.c
>>> > +++ b/drivers/of/device.c
>>> > @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>>> >
>>> >     /* name and id have to be set so that the platform bus doesn't get
>>> >      * confused on matching */
>>> > -   ofdev->name = dev_name(&ofdev->dev);
>>> > +   ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>>> >     ofdev->id = -1;
>>> >
>>> >     /* device_add will assume that this device is on the same node as
>>> > @@ -76,6 +76,7 @@ EXPORT_SYMBOL(of_device_register);
>>> >  void of_device_unregister(struct platform_device *ofdev)
>>> >  {
>>> >     device_unregister(&ofdev->dev);
>>> > +   kfree(ofdev->name);
>>>
>>> This probably ought to be swapped because we don't know if ofdev isn't
>>> pointing to freed memory after device_unregister().
>>
>> Actually, the only safe place to free the memory is inside the
>> platform_device release function. platform_device_release() in
>> drivers/base/platform.c. Unfortunately there isn't a good way from that
>> function to figure out if the name has been allocated the 'OF' way.
>>
>> It is not safe to free it here because there could still be references
>> to the platform_device after device_unregister exits.
>
> We could fix the problem by making platform_device_alloc() also do a
> kstrdup() when assigning the name. Then the release function can
> unconditionally free the name field. Care to try that out?

I don't know how well received that will be though. The vast majority
of non-OF callers of platform_device_alloc() pass in a static string
that will never disappear.

Another possible solutions: Override the release function for platform
devices allocated by of_device_alloc() to free the name field.

g.

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

* Re: [PATCH v2] of: Deep-copy names of platform devices
  2014-08-13  2:30   ` [PATCH v2] " Stepan Moskovchenko
@ 2014-08-15 16:38     ` Rob Herring
  2014-08-16  4:19       ` Greg Kroah-Hartman
  2014-08-16 18:29       ` Grant Likely
  0 siblings, 2 replies; 13+ messages in thread
From: Rob Herring @ 2014-08-15 16:38 UTC (permalink / raw)
  To: Stepan Moskovchenko
  Cc: Grant Likely, Rob Herring, devicetree, linux-kernel,
	linux-arm-msm, Greg Kroah-Hartman

Adding Greg...

On Tue, Aug 12, 2014 at 9:30 PM, Stepan Moskovchenko
<stepanm@codeaurora.org> wrote:
> When we parse the device tree and allocate platform
> devices, the 'name' of the newly-created platform_device
> is set to point to the 'name' field of the 'struct device'
> embedded within the platform_device. This is dangerous,
> because the name of the 'struct device' is dynamically
> allocated. Drivers may call dev_set_name() on the device,
> which will free and reallocate the name of the device,
> leaving the 'name' of the platform_device pointing to the
> now-freed memory.
>
> Furthermore, if the dev_set_name() call is made from a
> driver's probe() function and a subsequent request results
> in probe deferral, the dangling 'name' reference may lead
> to the device being re-probed using the wrong driver.

This seems wrong. I don't think we want drivers to change their own
device's name. The name is not supposed to change after registration.

Rob

> To mitigate these scenarios, we use kstrdup to perform a
> deep copy of the device name when assigning the name of the
> platform_device, so that the platform_device name is
> unaffected by any calls to dev_set_name() that might made
> by drivers to rename the embedded 'struct device'.
>
> Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
> ---
> * v2 - swap cleanup order
>
>  drivers/of/device.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index f685e55..e9beae6 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>
>         /* name and id have to be set so that the platform bus doesn't get
>          * confused on matching */
> -       ofdev->name = dev_name(&ofdev->dev);
> +       ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>         ofdev->id = -1;
>
>         /* device_add will assume that this device is on the same node as
> @@ -75,6 +75,7 @@ EXPORT_SYMBOL(of_device_register);
>
>  void of_device_unregister(struct platform_device *ofdev)
>  {
> +       kfree(ofdev->name);
>         device_unregister(&ofdev->dev);
>  }
>  EXPORT_SYMBOL(of_device_unregister);
> --
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> hosted by The Linux Foundation
>

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

* Re: [PATCH v2] of: Deep-copy names of platform devices
  2014-08-15 16:38     ` Rob Herring
@ 2014-08-16  4:19       ` Greg Kroah-Hartman
  2014-08-16 18:29       ` Grant Likely
  1 sibling, 0 replies; 13+ messages in thread
From: Greg Kroah-Hartman @ 2014-08-16  4:19 UTC (permalink / raw)
  To: Rob Herring
  Cc: Stepan Moskovchenko, Grant Likely, Rob Herring, devicetree,
	linux-kernel, linux-arm-msm

On Fri, Aug 15, 2014 at 11:38:33AM -0500, Rob Herring wrote:
> Adding Greg...
> 
> On Tue, Aug 12, 2014 at 9:30 PM, Stepan Moskovchenko
> <stepanm@codeaurora.org> wrote:
> > When we parse the device tree and allocate platform
> > devices, the 'name' of the newly-created platform_device
> > is set to point to the 'name' field of the 'struct device'
> > embedded within the platform_device. This is dangerous,
> > because the name of the 'struct device' is dynamically
> > allocated. Drivers may call dev_set_name() on the device,
> > which will free and reallocate the name of the device,
> > leaving the 'name' of the platform_device pointing to the
> > now-freed memory.
> >
> > Furthermore, if the dev_set_name() call is made from a
> > driver's probe() function and a subsequent request results
> > in probe deferral, the dangling 'name' reference may lead
> > to the device being re-probed using the wrong driver.
> 
> This seems wrong. I don't think we want drivers to change their own
> device's name. The name is not supposed to change after registration.

That is correct.  Well, you can change a name, using device_rename(),
but that's the only way to do it, not through dev_set_name(), as is
pointed out here, that will cause problems.

So I don't think this patch is needed at all.

thanks,

greg k-h

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

* Re: [PATCH v2] of: Deep-copy names of platform devices
  2014-08-15 16:38     ` Rob Herring
  2014-08-16  4:19       ` Greg Kroah-Hartman
@ 2014-08-16 18:29       ` Grant Likely
  1 sibling, 0 replies; 13+ messages in thread
From: Grant Likely @ 2014-08-16 18:29 UTC (permalink / raw)
  To: Rob Herring
  Cc: Stepan Moskovchenko, Rob Herring, devicetree, linux-kernel,
	linux-arm-msm, Greg Kroah-Hartman

On Fri, Aug 15, 2014 at 5:38 PM, Rob Herring <robherring2@gmail.com> wrote:
> Adding Greg...
>
> On Tue, Aug 12, 2014 at 9:30 PM, Stepan Moskovchenko
> <stepanm@codeaurora.org> wrote:
>> When we parse the device tree and allocate platform
>> devices, the 'name' of the newly-created platform_device
>> is set to point to the 'name' field of the 'struct device'
>> embedded within the platform_device. This is dangerous,
>> because the name of the 'struct device' is dynamically
>> allocated. Drivers may call dev_set_name() on the device,
>> which will free and reallocate the name of the device,
>> leaving the 'name' of the platform_device pointing to the
>> now-freed memory.
>>
>> Furthermore, if the dev_set_name() call is made from a
>> driver's probe() function and a subsequent request results
>> in probe deferral, the dangling 'name' reference may lead
>> to the device being re-probed using the wrong driver.
>
> This seems wrong. I don't think we want drivers to change their own
> device's name. The name is not supposed to change after registration.

Hmmm, you're right. The lifecycle question is theoretically valid but
it isn't something that should be done. In this case, it is the
drivers/of/platform code that 'owns' the name.

Stepan, under what circumstance would a device call dev_set_name()
after registration?

g.

>
> Rob
>
>> To mitigate these scenarios, we use kstrdup to perform a
>> deep copy of the device name when assigning the name of the
>> platform_device, so that the platform_device name is
>> unaffected by any calls to dev_set_name() that might made
>> by drivers to rename the embedded 'struct device'.
>>
>> Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
>> ---
>> * v2 - swap cleanup order
>>
>>  drivers/of/device.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index f685e55..e9beae6 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>>
>>         /* name and id have to be set so that the platform bus doesn't get
>>          * confused on matching */
>> -       ofdev->name = dev_name(&ofdev->dev);
>> +       ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>>         ofdev->id = -1;
>>
>>         /* device_add will assume that this device is on the same node as
>> @@ -75,6 +75,7 @@ EXPORT_SYMBOL(of_device_register);
>>
>>  void of_device_unregister(struct platform_device *ofdev)
>>  {
>> +       kfree(ofdev->name);
>>         device_unregister(&ofdev->dev);
>>  }
>>  EXPORT_SYMBOL(of_device_unregister);
>> --
>> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> hosted by The Linux Foundation
>>

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

* Re: [PATCH] of: Deep-copy names of platform devices
  2014-08-12 16:12 ` Kumar Gala
@ 2014-08-13  0:27   ` Stepan Moskovchenko
  0 siblings, 0 replies; 13+ messages in thread
From: Stepan Moskovchenko @ 2014-08-13  0:27 UTC (permalink / raw)
  To: Kumar Gala
  Cc: grant.likely, Rob Herring, devicetree-discuss, linux-kernel,
	linux-arm-msm

On 8/12/2014 9:12 AM, Kumar Gala wrote:
>
> On Aug 11, 2014, at 9:42 PM, Stepan Moskovchenko <stepanm@codeaurora.org> wrote:
>
>> When we parse the device tree and allocate platform
>> devices, the 'name' of the newly-created platform_device
>> is set to point to the 'name' field of the 'struct device'
>> embedded within the platform_device. This is dangerous,
>> because the name of the 'struct device' is dynamically
>> allocated. Drivers may call dev_set_name() on the device,
>> which will free and reallocate the name of the device,
>> leaving the 'name' of the platform_device pointing to the
>> now-freed memory.
>>
>> Furthermore, if the dev_set_name() call is made from a
>> driver's probe() function and a subsequent request results
>> in probe deferral, the dangling 'name' reference may lead
>> to the device being re-probed using the wrong driver.
>>
>> To mitigate these scenarios, we use kstrdup to perform a
>> deep copy of the device name when assigning the name of the
>> platform_device, so that the platform_device name is
>> unaffected by any calls to dev_set_name() that might made
>> by drivers to rename the embedded 'struct device'.
>>
>> Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
>> ---
>> I suppose creating a 'pdev_set_name' API may seem like
>> another possibility, but I feel that dev.name and pdev.name
>> have two different meanings. One is used for device/driver
>> binding purposes, whereas the other serves a more general
>> identification purpose, and is used for things like sysfs.
>> Drivers might want to change dev.name while leaving the
>> pdev.name alone. I guess yet another possibility would be
>> to prohibit calling dev_set_name() on devices created from
>> device tree, but a driver does not necessarily know how a
>> given platform_device was allocated.
>>
>> drivers/of/device.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index f685e55..fe5f025 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
>>
>> 	/* name and id have to be set so that the platform bus doesn't get
>> 	 * confused on matching */
>> -	ofdev->name = dev_name(&ofdev->dev);
>> +	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
>> 	ofdev->id = -1;
>>
>> 	/* device_add will assume that this device is on the same node as
>
> Don’t we need to free this is of_device_unregister() now?
>
> - k
>

Argh. I was confused by the asymmetric naming of the APIs, but after 
digging through the callers outside from drivers/of/, it looks like 
things do eventually filter down to of_device_add() in all the cases I 
could find. So yes, this does need to be fixed. Expect v2 soon.

Thanks
Steve

-- 
  The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
  hosted by The Linux Foundation

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

* Re: [PATCH] of: Deep-copy names of platform devices
  2014-08-12  2:42 Stepan Moskovchenko
@ 2014-08-12 16:12 ` Kumar Gala
  2014-08-13  0:27   ` Stepan Moskovchenko
  0 siblings, 1 reply; 13+ messages in thread
From: Kumar Gala @ 2014-08-12 16:12 UTC (permalink / raw)
  To: Stepan Moskovchenko
  Cc: grant.likely, Rob Herring, devicetree-discuss, linux-kernel,
	linux-arm-msm


On Aug 11, 2014, at 9:42 PM, Stepan Moskovchenko <stepanm@codeaurora.org> wrote:

> When we parse the device tree and allocate platform
> devices, the 'name' of the newly-created platform_device
> is set to point to the 'name' field of the 'struct device'
> embedded within the platform_device. This is dangerous,
> because the name of the 'struct device' is dynamically
> allocated. Drivers may call dev_set_name() on the device,
> which will free and reallocate the name of the device,
> leaving the 'name' of the platform_device pointing to the
> now-freed memory.
> 
> Furthermore, if the dev_set_name() call is made from a
> driver's probe() function and a subsequent request results
> in probe deferral, the dangling 'name' reference may lead
> to the device being re-probed using the wrong driver.
> 
> To mitigate these scenarios, we use kstrdup to perform a
> deep copy of the device name when assigning the name of the
> platform_device, so that the platform_device name is
> unaffected by any calls to dev_set_name() that might made
> by drivers to rename the embedded 'struct device'.
> 
> Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
> ---
> I suppose creating a 'pdev_set_name' API may seem like
> another possibility, but I feel that dev.name and pdev.name
> have two different meanings. One is used for device/driver
> binding purposes, whereas the other serves a more general
> identification purpose, and is used for things like sysfs.
> Drivers might want to change dev.name while leaving the
> pdev.name alone. I guess yet another possibility would be
> to prohibit calling dev_set_name() on devices created from
> device tree, but a driver does not necessarily know how a
> given platform_device was allocated.
> 
> drivers/of/device.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index f685e55..fe5f025 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)
> 
> 	/* name and id have to be set so that the platform bus doesn't get
> 	 * confused on matching */
> -	ofdev->name = dev_name(&ofdev->dev);
> +	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
> 	ofdev->id = -1;
> 
> 	/* device_add will assume that this device is on the same node as

Don’t we need to free this is of_device_unregister() now?

- k

> --
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> hosted by The Linux Foundation
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH] of: Deep-copy names of platform devices
@ 2014-08-12  2:42 Stepan Moskovchenko
  2014-08-12 16:12 ` Kumar Gala
  0 siblings, 1 reply; 13+ messages in thread
From: Stepan Moskovchenko @ 2014-08-12  2:42 UTC (permalink / raw)
  To: grant.likely, Rob Herring
  Cc: devicetree-discuss, linux-kernel, linux-arm-msm, stepanm

When we parse the device tree and allocate platform
devices, the 'name' of the newly-created platform_device
is set to point to the 'name' field of the 'struct device'
embedded within the platform_device. This is dangerous,
because the name of the 'struct device' is dynamically
allocated. Drivers may call dev_set_name() on the device,
which will free and reallocate the name of the device,
leaving the 'name' of the platform_device pointing to the
now-freed memory.

Furthermore, if the dev_set_name() call is made from a
driver's probe() function and a subsequent request results
in probe deferral, the dangling 'name' reference may lead
to the device being re-probed using the wrong driver.

To mitigate these scenarios, we use kstrdup to perform a
deep copy of the device name when assigning the name of the
platform_device, so that the platform_device name is
unaffected by any calls to dev_set_name() that might made
by drivers to rename the embedded 'struct device'.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
I suppose creating a 'pdev_set_name' API may seem like
another possibility, but I feel that dev.name and pdev.name
have two different meanings. One is used for device/driver
binding purposes, whereas the other serves a more general
identification purpose, and is used for things like sysfs.
Drivers might want to change dev.name while leaving the
pdev.name alone. I guess yet another possibility would be
to prohibit calling dev_set_name() on devices created from
device tree, but a driver does not necessarily know how a
given platform_device was allocated.

 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index f685e55..fe5f025 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -54,7 +54,7 @@ int of_device_add(struct platform_device *ofdev)

 	/* name and id have to be set so that the platform bus doesn't get
 	 * confused on matching */
-	ofdev->name = dev_name(&ofdev->dev);
+	ofdev->name = kstrdup(dev_name(&ofdev->dev), GFP_KERNEL);
 	ofdev->id = -1;

 	/* device_add will assume that this device is on the same node as
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

end of thread, other threads:[~2014-08-16 18:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-13  0:57 [PATCH] of: Deep-copy names of platform devices Stepan Moskovchenko
2014-08-13  1:46 ` Stephen Boyd
2014-08-13  2:30   ` [PATCH v2] " Stepan Moskovchenko
2014-08-15 16:38     ` Rob Herring
2014-08-16  4:19       ` Greg Kroah-Hartman
2014-08-16 18:29       ` Grant Likely
2014-08-15 10:45   ` [PATCH] " Grant Likely
2014-08-15 10:52     ` Grant Likely
     [not found]       ` <CACxGe6tr_hX+XBD=C+y55OixrweVLZvNNFQHxSDHwuHbSYW-XQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-08-15 11:01         ` Grant Likely
2014-08-15 11:01           ` Grant Likely
  -- strict thread matches above, loose matches on Subject: below --
2014-08-12  2:42 Stepan Moskovchenko
2014-08-12 16:12 ` Kumar Gala
2014-08-13  0:27   ` Stepan Moskovchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.