diff options
author | Axel Lin <axel.lin@gmail.com> | 2010-08-09 20:20:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-09 23:45:09 -0400 |
commit | 1986aaf828ac8398b3d8d9b4151b08c840414ffe (patch) | |
tree | ce5b6e92bab2e8f706ad2c9e08ac826bc5c215a2 /drivers | |
parent | ea98eed9bcb62d1319db8b1210712c6a110a886c (diff) |
edd: fix possible memory leak in edd_init() error path
The error may happen at any iteration of the for loop, this patch properly
unregisters already registed edd_devices in error path.
[akpm@linux-foundation.org: remove unneeded NULL test]
Signed-off-by: Axel Lin <axel.lin@gmail.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firmware/edd.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 110e24e50883..f287fe79edc4 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c | |||
@@ -744,7 +744,7 @@ static inline int edd_num_devices(void) | |||
744 | static int __init | 744 | static int __init |
745 | edd_init(void) | 745 | edd_init(void) |
746 | { | 746 | { |
747 | unsigned int i; | 747 | int i; |
748 | int rc=0; | 748 | int rc=0; |
749 | struct edd_device *edev; | 749 | struct edd_device *edev; |
750 | 750 | ||
@@ -760,21 +760,27 @@ edd_init(void) | |||
760 | if (!edd_kset) | 760 | if (!edd_kset) |
761 | return -ENOMEM; | 761 | return -ENOMEM; |
762 | 762 | ||
763 | for (i = 0; i < edd_num_devices() && !rc; i++) { | 763 | for (i = 0; i < edd_num_devices(); i++) { |
764 | edev = kzalloc(sizeof (*edev), GFP_KERNEL); | 764 | edev = kzalloc(sizeof (*edev), GFP_KERNEL); |
765 | if (!edev) | 765 | if (!edev) { |
766 | return -ENOMEM; | 766 | rc = -ENOMEM; |
767 | goto out; | ||
768 | } | ||
767 | 769 | ||
768 | rc = edd_device_register(edev, i); | 770 | rc = edd_device_register(edev, i); |
769 | if (rc) { | 771 | if (rc) { |
770 | kfree(edev); | 772 | kfree(edev); |
771 | break; | 773 | goto out; |
772 | } | 774 | } |
773 | edd_devices[i] = edev; | 775 | edd_devices[i] = edev; |
774 | } | 776 | } |
775 | 777 | ||
776 | if (rc) | 778 | return 0; |
777 | kset_unregister(edd_kset); | 779 | |
780 | out: | ||
781 | while (--i >= 0) | ||
782 | edd_device_unregister(edd_devices[i]); | ||
783 | kset_unregister(edd_kset); | ||
778 | return rc; | 784 | return rc; |
779 | } | 785 | } |
780 | 786 | ||