powerpc/fsl_rio: Add kmalloc NULL tests
authorJulia Lawall <julia@diku.dk>
Fri, 7 Aug 2009 07:00:34 +0000 (09:00 +0200)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 20 Aug 2009 00:27:17 +0000 (10:27 +1000)
Check that the result of kmalloc/kzalloc is not NULL before dereferencing it.

The semantic match that finds this problem is as follows:
(http://coccinelle.lip6.fr/)

// <smpl>
@@
expression *x;
identifier f;
constant char *C;
@@

x = \(kmalloc\|kcalloc\|kzalloc\)(...);
... when != x == NULL
    when != x != NULL
    when != (x || ...)
(
kfree(x)
|
f(...,C,...,x,...)
|
*f(...,x,...)
|
*x->f
)
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/sysdev/fsl_rio.c

index cbb3bed..757a83f 100644 (file)
@@ -1057,6 +1057,10 @@ int fsl_rio_setup(struct of_device *dev)
                        law_start, law_size);
 
        ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
+       if (!ops) {
+               rc = -ENOMEM;
+               goto err_ops;
+       }
        ops->lcread = fsl_local_config_read;
        ops->lcwrite = fsl_local_config_write;
        ops->cread = fsl_rio_config_read;
@@ -1064,6 +1068,10 @@ int fsl_rio_setup(struct of_device *dev)
        ops->dsend = fsl_rio_doorbell_send;
 
        port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
+       if (!port) {
+               rc = -ENOMEM;
+               goto err_port;
+       }
        port->id = 0;
        port->index = 0;
 
@@ -1071,7 +1079,7 @@ int fsl_rio_setup(struct of_device *dev)
        if (!priv) {
                printk(KERN_ERR "Can't alloc memory for 'priv'\n");
                rc = -ENOMEM;
-               goto err;
+               goto err_priv;
        }
 
        INIT_LIST_HEAD(&port->dbells);
@@ -1169,11 +1177,13 @@ int fsl_rio_setup(struct of_device *dev)
 
        return 0;
 err:
-       if (priv)
-               iounmap(priv->regs_win);
-       kfree(ops);
+       iounmap(priv->regs_win);
        kfree(priv);
+err_priv:
        kfree(port);
+err_port:
+       kfree(ops);
+err_ops:
        return rc;
 }