Commit 2ffcab6a authored by Tom Tucker's avatar Tom Tucker Committed by Roland Dreier
Browse files

RDMA/amso1100: Fix unitialized pseudo_netdev accessed in c2_register_device



Rework some load-time error handling: c2_register_device() leaked when
it failed, and the function that called it didn't check the return code.

Signed-off-by: default avatarTom Tucker <tom@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent f2c238a0
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -1155,7 +1155,8 @@ static int __devinit c2_probe(struct pci_dev *pcidev,
		goto bail10;
		goto bail10;
	}
	}


	c2_register_device(c2dev);
	if (c2_register_device(c2dev))
		goto bail10;


	return 0;
	return 0;


+20 −19
Original line number Original line Diff line number Diff line
@@ -757,20 +757,17 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)


int c2_register_device(struct c2_dev *dev)
int c2_register_device(struct c2_dev *dev)
{
{
	int ret;
	int ret = -ENOMEM;
	int i;
	int i;


	/* Register pseudo network device */
	/* Register pseudo network device */
	dev->pseudo_netdev = c2_pseudo_netdev_init(dev);
	dev->pseudo_netdev = c2_pseudo_netdev_init(dev);
	if (dev->pseudo_netdev) {
	if (!dev->pseudo_netdev)
		goto out3;

	ret = register_netdev(dev->pseudo_netdev);
	ret = register_netdev(dev->pseudo_netdev);
		if (ret) {
	if (ret)
			printk(KERN_ERR PFX
		goto out2;
				"Unable to register netdev, ret = %d\n", ret);
			free_netdev(dev->pseudo_netdev);
			return ret;
		}
	}


	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
	strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);
	strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);
@@ -848,22 +845,26 @@ int c2_register_device(struct c2_dev *dev)


	ret = ib_register_device(&dev->ibdev);
	ret = ib_register_device(&dev->ibdev);
	if (ret)
	if (ret)
		return ret;
		goto out1;


	for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) {
	for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) {
		ret = class_device_create_file(&dev->ibdev.class_dev,
		ret = class_device_create_file(&dev->ibdev.class_dev,
					       c2_class_attributes[i]);
					       c2_class_attributes[i]);
		if (ret) {
		if (ret)
			goto out0;
	}
	goto out3;

out0:
	ib_unregister_device(&dev->ibdev);
out1:
	unregister_netdev(dev->pseudo_netdev);
	unregister_netdev(dev->pseudo_netdev);
out2:
	free_netdev(dev->pseudo_netdev);
	free_netdev(dev->pseudo_netdev);
			ib_unregister_device(&dev->ibdev);
out3:
	pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret);
	return ret;
	return ret;
}
}
	}

	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
	return 0;
}


void c2_unregister_device(struct c2_dev *dev)
void c2_unregister_device(struct c2_dev *dev)
{
{