diff options
author | Jean Delvare <jdelvare@suse.de> | 2014-02-24 14:45:34 (GMT) |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2014-02-25 09:09:09 (GMT) |
commit | 5576fb8696bf8d8ae60278c2aa4dc23eae9eb86e (patch) | |
tree | 0f33e5b6fca077299ff6a8f5bfccc5522bc85702 | |
parent | 0e089c182889e1551dcaaea8ee1639bfa81896a3 (diff) | |
download | linux-5576fb8696bf8d8ae60278c2aa4dc23eae9eb86e.tar.xz |
amd8111_edac: Fix leaks in probe error paths
Both probe error paths are incomplete and leak memory and device
references. Add the missing cleanups.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Link: http://lkml.kernel.org/r/20140224154534.5a3b797a@endymion.delvare
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r-- | drivers/edac/amd8111_edac.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/edac/amd8111_edac.c b/drivers/edac/amd8111_edac.c index ddd8900..2b63f7c 100644 --- a/drivers/edac/amd8111_edac.c +++ b/drivers/edac/amd8111_edac.c @@ -350,6 +350,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data]; + int ret = -ENODEV; dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, dev_info->err_dev, NULL); @@ -359,16 +360,15 @@ static int amd8111_dev_probe(struct pci_dev *dev, "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, dev_info->err_dev, dev_info->ctl_name); - return -ENODEV; + goto err; } if (pci_enable_device(dev_info->dev)) { - pci_dev_put(dev_info->dev); printk(KERN_ERR "failed to enable:" "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, dev_info->err_dev, dev_info->ctl_name); - return -ENODEV; + goto err_dev_put; } /* @@ -381,8 +381,10 @@ static int amd8111_dev_probe(struct pci_dev *dev, edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, NULL, 0, 0, NULL, 0, dev_info->edac_idx); - if (!dev_info->edac_dev) - return -ENOMEM; + if (!dev_info->edac_dev) { + ret = -ENOMEM; + goto err_dev_put; + } dev_info->edac_dev->pvt_info = dev_info; dev_info->edac_dev->dev = &dev_info->dev->dev; @@ -399,8 +401,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, if (edac_device_add_device(dev_info->edac_dev) > 0) { printk(KERN_ERR "failed to add edac_dev for %s\n", dev_info->ctl_name); - edac_device_free_ctl_info(dev_info->edac_dev); - return -ENODEV; + goto err_edac_free_ctl; } printk(KERN_INFO "added one edac_dev on AMD8111 " @@ -409,6 +410,13 @@ static int amd8111_dev_probe(struct pci_dev *dev, dev_info->ctl_name); return 0; + +err_edac_free_ctl: + edac_device_free_ctl_info(dev_info->edac_dev); +err_dev_put: + pci_dev_put(dev_info->dev); +err: + return ret; } static void amd8111_dev_remove(struct pci_dev *dev) @@ -437,6 +445,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data]; + int ret = -ENODEV; pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, pci_info->err_dev, NULL); @@ -446,16 +455,15 @@ static int amd8111_pci_probe(struct pci_dev *dev, "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, pci_info->err_dev, pci_info->ctl_name); - return -ENODEV; + goto err; } if (pci_enable_device(pci_info->dev)) { - pci_dev_put(pci_info->dev); printk(KERN_ERR "failed to enable:" "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, pci_info->err_dev, pci_info->ctl_name); - return -ENODEV; + goto err_dev_put; } /* @@ -465,8 +473,10 @@ static int amd8111_pci_probe(struct pci_dev *dev, */ pci_info->edac_idx = edac_pci_alloc_index(); pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name); - if (!pci_info->edac_dev) - return -ENOMEM; + if (!pci_info->edac_dev) { + ret = -ENOMEM; + goto err_dev_put; + } pci_info->edac_dev->pvt_info = pci_info; pci_info->edac_dev->dev = &pci_info->dev->dev; @@ -483,8 +493,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) { printk(KERN_ERR "failed to add edac_pci for %s\n", pci_info->ctl_name); - edac_pci_free_ctl_info(pci_info->edac_dev); - return -ENODEV; + goto err_edac_free_ctl; } printk(KERN_INFO "added one edac_pci on AMD8111 " @@ -493,6 +502,13 @@ static int amd8111_pci_probe(struct pci_dev *dev, pci_info->ctl_name); return 0; + +err_edac_free_ctl: + edac_pci_free_ctl_info(pci_info->edac_dev); +err_dev_put: + pci_dev_put(pci_info->dev); +err: + return ret; } static void amd8111_pci_remove(struct pci_dev *dev) |