Skip to content

Commit

Permalink
amd8111_edac: Fix leaks in probe error paths
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean Delvare authored and Borislav Petkov committed Feb 25, 2014
1 parent 0e089c1 commit 5576fb8
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions drivers/edac/amd8111_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

/*
Expand All @@ -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;
Expand All @@ -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 "
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

/*
Expand All @@ -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;
Expand All @@ -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 "
Expand All @@ -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)
Expand Down

0 comments on commit 5576fb8

Please sign in to comment.