diff mbox

mtd: nand: mxc_nand: fix a possible NULL dereference

Message ID 1447314423-31225-1-git-send-email-clabbe.montjoie@gmail.com
State Changes Requested
Headers show

Commit Message

Corentin Labbe Nov. 12, 2015, 7:46 a.m. UTC
of_match_device could return NULL, and so cause a NULL pointer
dereference later.

Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
---
 drivers/mtd/nand/mxc_nand.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Frans Klaver Nov. 12, 2015, 8:03 a.m. UTC | #1
Hi,

On Thu, Nov 12, 2015 at 8:46 AM, LABBE Corentin
<clabbe.montjoie@gmail.com> wrote:
> of_match_device could return NULL, and so cause a NULL pointer
> dereference later.

Did you actually run into this? It seems to me that this driver is
only probed if and only if we have a match and that therefore
of_match_device will always return a valid pointer (it is using the
same match table). Am I missing something?


> Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
> ---
>  drivers/mtd/nand/mxc_nand.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 136e73a..9e42431 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -1464,8 +1464,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
>  {
>         struct device_node *np = host->dev->of_node;
>         struct mxc_nand_platform_data *pdata = &host->pdata;
> -       const struct of_device_id *of_id =
> -               of_match_device(mxcnd_dt_ids, host->dev);
> +       const struct of_device_id *of_id;
>         int buswidth;
>
>         if (!np)
> @@ -1482,6 +1481,9 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
>
>         pdata->width = buswidth / 8;
>
> +       of_id = of_match_device(mxcnd_dt_ids, host->dev);
> +       if (!of_id)
> +               return -ENODEV;
>         host->devtype_data = of_id->data;
>
>         return 0;
> --
> 2.4.10
>

Thanks,
Frans
Uwe Kleine-König Nov. 12, 2015, 8:19 a.m. UTC | #2
Hello Corentin,

On Thu, Nov 12, 2015 at 08:46:55AM +0100, LABBE Corentin wrote:
> of_match_device could return NULL, and so cause a NULL pointer
> dereference later.
> 
> Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
> ---
>  drivers/mtd/nand/mxc_nand.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 136e73a..9e42431 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -1464,8 +1464,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
>  {
>  	struct device_node *np = host->dev->of_node;
>  	struct mxc_nand_platform_data *pdata = &host->pdata;
> -	const struct of_device_id *of_id =
> -		of_match_device(mxcnd_dt_ids, host->dev);
> +	const struct of_device_id *of_id;
>  	int buswidth;
>  
>  	if (!np)
> @@ -1482,6 +1481,9 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
>  
>  	pdata->width = buswidth / 8;
>  
> +	of_id = of_match_device(mxcnd_dt_ids, host->dev);
> +	if (!of_id)
> +		return -ENODEV;

You should return 1 here instead of -ENODEV. Also this check should
better be done instead of

	if (!np)
		return 1;

at the start of the function. I really wonder there is no helper
function like:

	#define of_sensible_name(dev)	of_match_device(dev->driver->of_match_table, dev)

Best regards
Uwe

>  	host->devtype_data = of_id->data;
>  
>  	return 0;
> -- 
> 2.4.10
> 
>
Uwe Kleine-König Nov. 12, 2015, 8:26 a.m. UTC | #3
On Thu, Nov 12, 2015 at 09:03:11AM +0100, Frans Klaver wrote:
> Hi,
> 
> On Thu, Nov 12, 2015 at 8:46 AM, LABBE Corentin
> <clabbe.montjoie@gmail.com> wrote:
> > of_match_device could return NULL, and so cause a NULL pointer
> > dereference later.
> 
> Did you actually run into this? It seems to me that this driver is
> only probed if and only if we have a match and that therefore
> of_match_device will always return a valid pointer (it is using the
> same match table). Am I missing something?

Yes, you're missing something. The driver would probe for a dt snippet
like:

	mxc_nand {
		compatible = "foobar";
	}

In this case dev->of_node is non-NULL but of_match_device(mxcnd_dt_ids,
dev) is.

(I didn't actually test this, so there is a chance I'm wrong here. And
if not I wonder if it is sensible at all to match the device name on
driver name for of-created platform devices.)

Best regards
Uwe
Frans Klaver Nov. 12, 2015, 8:36 a.m. UTC | #4
On Thu, Nov 12, 2015 at 9:26 AM, Uwe Kleine-König
<u.kleine-koenig@pengutronix.de> wrote:
> On Thu, Nov 12, 2015 at 09:03:11AM +0100, Frans Klaver wrote:
>> Hi,
>>
>> On Thu, Nov 12, 2015 at 8:46 AM, LABBE Corentin
>> <clabbe.montjoie@gmail.com> wrote:
>> > of_match_device could return NULL, and so cause a NULL pointer
>> > dereference later.
>>
>> Did you actually run into this? It seems to me that this driver is
>> only probed if and only if we have a match and that therefore
>> of_match_device will always return a valid pointer (it is using the
>> same match table). Am I missing something?
>
> Yes, you're missing something. The driver would probe for a dt snippet
> like:
>
>         mxc_nand {
>                 compatible = "foobar";
>         }
>
> In this case dev->of_node is non-NULL but of_match_device(mxcnd_dt_ids,
> dev) is.
>
> (I didn't actually test this, so there is a chance I'm wrong here. And
> if not I wonder if it is sensible at all to match the device name on
> driver name for of-created platform devices.)

Yea, looks like you're right. platform devices check a number of
things to determine a match, among which is driver name if all else
fails (platform.c, platform_match()).

Thanks,
Frans
LABBE Corentin Nov. 12, 2015, 10:03 a.m. UTC | #5
On Thu, Nov 12, 2015 at 09:19:09AM +0100, Uwe Kleine-König wrote:
> Hello Corentin,
> 
> On Thu, Nov 12, 2015 at 08:46:55AM +0100, LABBE Corentin wrote:
> > of_match_device could return NULL, and so cause a NULL pointer
> > dereference later.
> > 
> > Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
> > ---
> >  drivers/mtd/nand/mxc_nand.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > index 136e73a..9e42431 100644
> > --- a/drivers/mtd/nand/mxc_nand.c
> > +++ b/drivers/mtd/nand/mxc_nand.c
> > @@ -1464,8 +1464,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
> >  {
> >  	struct device_node *np = host->dev->of_node;
> >  	struct mxc_nand_platform_data *pdata = &host->pdata;
> > -	const struct of_device_id *of_id =
> > -		of_match_device(mxcnd_dt_ids, host->dev);
> > +	const struct of_device_id *of_id;
> >  	int buswidth;
> >  
> >  	if (!np)
> > @@ -1482,6 +1481,9 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
> >  
> >  	pdata->width = buswidth / 8;
> >  
> > +	of_id = of_match_device(mxcnd_dt_ids, host->dev);
> > +	if (!of_id)
> > +		return -ENODEV;
> 
> You should return 1 here instead of -ENODEV. Also this check should
> better be done instead of
> 
> 	if (!np)
> 		return 1;
> 
> at the start of the function.

Are you sure for the "1" value ? It seems a very bad error value.
And I found plenty of case where if (!np) return -Esomething and no example of return 1

Regards
Uwe Kleine-König Nov. 12, 2015, 10:14 a.m. UTC | #6
Hello,

On Thu, Nov 12, 2015 at 11:03:28AM +0100, LABBE Corentin wrote:
> On Thu, Nov 12, 2015 at 09:19:09AM +0100, Uwe Kleine-König wrote:
> > Hello Corentin,
> > 
> > On Thu, Nov 12, 2015 at 08:46:55AM +0100, LABBE Corentin wrote:
> > > of_match_device could return NULL, and so cause a NULL pointer
> > > dereference later.
> > > 
> > > Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
> > > ---
> > >  drivers/mtd/nand/mxc_nand.c | 6 ++++--
> > >  1 file changed, 4 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > > index 136e73a..9e42431 100644
> > > --- a/drivers/mtd/nand/mxc_nand.c
> > > +++ b/drivers/mtd/nand/mxc_nand.c
> > > @@ -1464,8 +1464,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
> > >  {
> > >  	struct device_node *np = host->dev->of_node;
> > >  	struct mxc_nand_platform_data *pdata = &host->pdata;
> > > -	const struct of_device_id *of_id =
> > > -		of_match_device(mxcnd_dt_ids, host->dev);
> > > +	const struct of_device_id *of_id;
> > >  	int buswidth;
> > >  
> > >  	if (!np)
> > > @@ -1482,6 +1481,9 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
> > >  
> > >  	pdata->width = buswidth / 8;
> > >  
> > > +	of_id = of_match_device(mxcnd_dt_ids, host->dev);
> > > +	if (!of_id)
> > > +		return -ENODEV;
> > 
> > You should return 1 here instead of -ENODEV. Also this check should
> > better be done instead of
> > 
> > 	if (!np)
> > 		return 1;
> > 
> > at the start of the function.
> 
> Are you sure for the "1" value ? It seems a very bad error value.
> And I found plenty of case where if (!np) return -Esomething and no example of return 1

This is not an error value. The semantic is:

	0	everything ok, initialized from dt
	1	device was not probed by dt -> fall back to board-file stuff
	<0	error that should abort probing

Best regards
Uwe
Brian Norris Nov. 16, 2015, 6:33 p.m. UTC | #7
On Thu, Nov 12, 2015 at 09:19:09AM +0100, Uwe Kleine-König wrote:
> I really wonder there is no helper
> function like:
> 
> 	#define of_sensible_name(dev)	of_match_device(dev->driver->of_match_table, dev)

How about of_device_get_match_data()?

It's not exactly what you asked for, but it gets what you need here.

Brian
Corentin Labbe Nov. 16, 2015, 7:12 p.m. UTC | #8
Le 16/11/2015 19:33, Brian Norris a écrit :
> On Thu, Nov 12, 2015 at 09:19:09AM +0100, Uwe Kleine-König wrote:
>> I really wonder there is no helper
>> function like:
>>
>> 	#define of_sensible_name(dev)	of_match_device(dev->driver->of_match_table, dev)
> 
> How about of_device_get_match_data()?
> 
> It's not exactly what you asked for, but it gets what you need here.
> 
> Brian
> 

I have got the same comment from another thread.
I will use it. Thanks

Regards
diff mbox

Patch

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 136e73a..9e42431 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1464,8 +1464,7 @@  static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
 {
 	struct device_node *np = host->dev->of_node;
 	struct mxc_nand_platform_data *pdata = &host->pdata;
-	const struct of_device_id *of_id =
-		of_match_device(mxcnd_dt_ids, host->dev);
+	const struct of_device_id *of_id;
 	int buswidth;
 
 	if (!np)
@@ -1482,6 +1481,9 @@  static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
 
 	pdata->width = buswidth / 8;
 
+	of_id = of_match_device(mxcnd_dt_ids, host->dev);
+	if (!of_id)
+		return -ENODEV;
 	host->devtype_data = of_id->data;
 
 	return 0;