diff options
author | Yinghai Lu <yinghai@kernel.org> | 2010-08-10 21:03:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-11 11:59:20 -0400 |
commit | 7faefea66a6d1f0d9da0a18615f57dc969e00d99 (patch) | |
tree | a3035d4e86df7460840e7d4991178375b465b918 | |
parent | f46c77c283e514a747aee7e8c4f5afc70274c232 (diff) |
ipmi: fix memleaking for add_smi when duplicating happen
Free the temporary info struct when we have duplicated ones.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Corey Minyard <minyard@acm.org>
Cc: Matthew Garrett <mjg@redhat.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Myron Stowe <myron.stowe@hp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index ecfe43beb9c2..6c2daed531df 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1804,9 +1804,12 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1804 | info->irq_setup = std_irq_setup; | 1804 | info->irq_setup = std_irq_setup; |
1805 | info->slave_addr = ipmb; | 1805 | info->slave_addr = ipmb; |
1806 | 1806 | ||
1807 | if (!add_smi(info)) | 1807 | if (!add_smi(info)) { |
1808 | if (try_smi_init(info)) | 1808 | if (try_smi_init(info)) |
1809 | cleanup_one_si(info); | 1809 | cleanup_one_si(info); |
1810 | } else { | ||
1811 | kfree(info); | ||
1812 | } | ||
1810 | } else { | 1813 | } else { |
1811 | /* remove */ | 1814 | /* remove */ |
1812 | struct smi_info *e, *tmp_e; | 1815 | struct smi_info *e, *tmp_e; |
@@ -1890,9 +1893,12 @@ static __devinit void hardcode_find_bmc(void) | |||
1890 | info->irq_setup = std_irq_setup; | 1893 | info->irq_setup = std_irq_setup; |
1891 | info->slave_addr = slave_addrs[i]; | 1894 | info->slave_addr = slave_addrs[i]; |
1892 | 1895 | ||
1893 | if (!add_smi(info)) | 1896 | if (!add_smi(info)) { |
1894 | if (try_smi_init(info)) | 1897 | if (try_smi_init(info)) |
1895 | cleanup_one_si(info); | 1898 | cleanup_one_si(info); |
1899 | } else { | ||
1900 | kfree(info); | ||
1901 | } | ||
1896 | } | 1902 | } |
1897 | } | 1903 | } |
1898 | 1904 | ||
@@ -2082,7 +2088,8 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) | |||
2082 | } | 2088 | } |
2083 | info->io.addr_data = spmi->addr.address; | 2089 | info->io.addr_data = spmi->addr.address; |
2084 | 2090 | ||
2085 | add_smi(info); | 2091 | if (add_smi(info)) |
2092 | kfree(info); | ||
2086 | 2093 | ||
2087 | return 0; | 2094 | return 0; |
2088 | } | 2095 | } |
@@ -2198,7 +2205,10 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2198 | res, info->io.regsize, info->io.regspacing, | 2205 | res, info->io.regsize, info->io.regspacing, |
2199 | info->irq); | 2206 | info->irq); |
2200 | 2207 | ||
2201 | return add_smi(info); | 2208 | if (add_smi(info)) |
2209 | goto err_free; | ||
2210 | |||
2211 | return 0; | ||
2202 | 2212 | ||
2203 | err_free: | 2213 | err_free: |
2204 | kfree(info); | 2214 | kfree(info); |
@@ -2356,7 +2366,8 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) | |||
2356 | if (info->irq) | 2366 | if (info->irq) |
2357 | info->irq_setup = std_irq_setup; | 2367 | info->irq_setup = std_irq_setup; |
2358 | 2368 | ||
2359 | add_smi(info); | 2369 | if (add_smi(info)) |
2370 | kfree(info); | ||
2360 | } | 2371 | } |
2361 | 2372 | ||
2362 | static void __devinit dmi_find_bmc(void) | 2373 | static void __devinit dmi_find_bmc(void) |
@@ -2462,7 +2473,10 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2462 | &pdev->resource[0], info->io.regsize, info->io.regspacing, | 2473 | &pdev->resource[0], info->io.regsize, info->io.regspacing, |
2463 | info->irq); | 2474 | info->irq); |
2464 | 2475 | ||
2465 | return add_smi(info); | 2476 | if (add_smi(info)) |
2477 | kfree(info); | ||
2478 | |||
2479 | return 0; | ||
2466 | } | 2480 | } |
2467 | 2481 | ||
2468 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) | 2482 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) |
@@ -2575,7 +2589,12 @@ static int __devinit ipmi_of_probe(struct of_device *dev, | |||
2575 | 2589 | ||
2576 | dev_set_drvdata(&dev->dev, info); | 2590 | dev_set_drvdata(&dev->dev, info); |
2577 | 2591 | ||
2578 | return add_smi(info); | 2592 | if (add_smi(info)) { |
2593 | kfree(info); | ||
2594 | return -EBUSY; | ||
2595 | } | ||
2596 | |||
2597 | return 0; | ||
2579 | } | 2598 | } |
2580 | 2599 | ||
2581 | static int __devexit ipmi_of_remove(struct of_device *dev) | 2600 | static int __devexit ipmi_of_remove(struct of_device *dev) |
@@ -3008,6 +3027,8 @@ static __devinit void default_find_bmc(void) | |||
3008 | info->io.addr_data); | 3027 | info->io.addr_data); |
3009 | } else | 3028 | } else |
3010 | cleanup_one_si(info); | 3029 | cleanup_one_si(info); |
3030 | } else { | ||
3031 | kfree(info); | ||
3011 | } | 3032 | } |
3012 | } | 3033 | } |
3013 | } | 3034 | } |