[ofa-general] [PATCH] IB: dereference of dev->ibdev.iwcm in c2_register_device()

Roel Kluin roel.kluin at gmail.com
Tue Sep 1 07:03:08 PDT 2009


dev->ibdev.iwcm allocation may fail, prevent a dereference.

Signed-off-by: Roel Kluin <roel.kluin at gmail.com>
---
> Looks like a real fix to me -- but then don't we need to kfree() this
> memory if any of the later initialization fails (to avoid a leak)?

Ok, how about this?

diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index f1948fa..3f2ee64 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -780,11 +780,11 @@ int c2_register_device(struct c2_dev *dev)
 	/* Register pseudo network device */
 	dev->pseudo_netdev = c2_pseudo_netdev_init(dev);
 	if (!dev->pseudo_netdev)
-		goto out3;
+		goto out;
 
 	ret = register_netdev(dev->pseudo_netdev);
 	if (ret)
-		goto out2;
+		goto out_free_netdev;
 
 	pr_debug("%s:%u\n", __func__, __LINE__);
 	strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);
@@ -851,6 +851,10 @@ int c2_register_device(struct c2_dev *dev)
 	dev->ibdev.post_recv = c2_post_receive;
 
 	dev->ibdev.iwcm = kmalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL);
+	if (dev->ibdev.iwcm == NULL) {
+		ret = -ENOMEM;
+		goto out_unregister_netdev;
+	}
 	dev->ibdev.iwcm->add_ref = c2_add_ref;
 	dev->ibdev.iwcm->rem_ref = c2_rem_ref;
 	dev->ibdev.iwcm->get_qp = c2_get_qp;
@@ -862,23 +866,25 @@ int c2_register_device(struct c2_dev *dev)
 
 	ret = ib_register_device(&dev->ibdev);
 	if (ret)
-		goto out1;
+		goto out_free_iwcm;
 
 	for (i = 0; i < ARRAY_SIZE(c2_dev_attributes); ++i) {
 		ret = device_create_file(&dev->ibdev.dev,
 					       c2_dev_attributes[i]);
 		if (ret)
-			goto out0;
+			goto out_unregister_ibdev;
 	}
 	goto out3;
 
-out0:
+out_unregister_ibdev:
 	ib_unregister_device(&dev->ibdev);
-out1:
+out_free_iwcm:
+	kfree(dev->ibdev.iwcm);
+out_unregister_netdev:
 	unregister_netdev(dev->pseudo_netdev);
-out2:
+out_free_netdev:
 	free_netdev(dev->pseudo_netdev);
-out3:
+out:
 	pr_debug("%s:%u ret=%d\n", __func__, __LINE__, ret);
 	return ret;
 }



More information about the general mailing list