diff mbox

[v2] of: Deep-copy names of platform devices

Message ID 1407897037-6037-1-git-send-email-stepanm@codeaurora.org (mailing list archive)
State New, archived
Headers show

Commit Message

stepanm@codeaurora.org Aug. 13, 2014, 2:30 a.m. UTC
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(-)

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

Comments

Rob Herring Aug. 15, 2014, 4:38 p.m. UTC | #1
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
>
--
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
Greg Kroah-Hartman Aug. 16, 2014, 4:19 a.m. UTC | #2
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
--
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
grant.likely@linaro.org Aug. 16, 2014, 6:29 p.m. UTC | #3
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
>>
--
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
diff mbox

Patch

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