diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-10-06 16:38:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 19:47:43 -0400 |
commit | a922c68732725866c88457026cf06a7620846506 (patch) | |
tree | e859a07f850fa62fc7e8494737b9a4830fdb936c /drivers/usb/gadget/file_storage.c | |
parent | 3f8c03ee05801bf8539dd136d9246a416c45052a (diff) |
[PATCH] g_file_storage: fix obscure race condition
This patch (as575) fixes an unlikely race in the g_file_storage driver.
The problem can occur only when the driver is unbound before its
initialization routine has finished.
I also took the opportunity to replace kmalloc/memset with kzalloc.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 241c570e541..86a6aeb9ed7 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -3823,12 +3823,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3823 | 3823 | ||
3824 | /* Create the LUNs, open their backing files, and register the | 3824 | /* Create the LUNs, open their backing files, and register the |
3825 | * LUN devices in sysfs. */ | 3825 | * LUN devices in sysfs. */ |
3826 | fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL); | 3826 | fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL); |
3827 | if (!fsg->luns) { | 3827 | if (!fsg->luns) { |
3828 | rc = -ENOMEM; | 3828 | rc = -ENOMEM; |
3829 | goto out; | 3829 | goto out; |
3830 | } | 3830 | } |
3831 | memset(fsg->luns, 0, i * sizeof(struct lun)); | ||
3832 | fsg->nluns = i; | 3831 | fsg->nluns = i; |
3833 | 3832 | ||
3834 | for (i = 0; i < fsg->nluns; ++i) { | 3833 | for (i = 0; i < fsg->nluns; ++i) { |
@@ -3989,6 +3988,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3989 | mod_data.removable, mod_data.can_stall, | 3988 | mod_data.removable, mod_data.can_stall, |
3990 | mod_data.buflen); | 3989 | mod_data.buflen); |
3991 | DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); | 3990 | DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); |
3991 | |||
3992 | set_bit(REGISTERED, &fsg->atomic_bitflags); | ||
3993 | |||
3994 | /* Tell the thread to start working */ | ||
3995 | wake_up_process(fsg->thread_task); | ||
3992 | return 0; | 3996 | return 0; |
3993 | 3997 | ||
3994 | autoconf_fail: | 3998 | autoconf_fail: |
@@ -4051,10 +4055,9 @@ static int __init fsg_alloc(void) | |||
4051 | { | 4055 | { |
4052 | struct fsg_dev *fsg; | 4056 | struct fsg_dev *fsg; |
4053 | 4057 | ||
4054 | fsg = kmalloc(sizeof *fsg, GFP_KERNEL); | 4058 | fsg = kzalloc(sizeof *fsg, GFP_KERNEL); |
4055 | if (!fsg) | 4059 | if (!fsg) |
4056 | return -ENOMEM; | 4060 | return -ENOMEM; |
4057 | memset(fsg, 0, sizeof *fsg); | ||
4058 | spin_lock_init(&fsg->lock); | 4061 | spin_lock_init(&fsg->lock); |
4059 | init_rwsem(&fsg->filesem); | 4062 | init_rwsem(&fsg->filesem); |
4060 | init_waitqueue_head(&fsg->thread_wqh); | 4063 | init_waitqueue_head(&fsg->thread_wqh); |
@@ -4080,15 +4083,9 @@ static int __init fsg_init(void) | |||
4080 | if ((rc = fsg_alloc()) != 0) | 4083 | if ((rc = fsg_alloc()) != 0) |
4081 | return rc; | 4084 | return rc; |
4082 | fsg = the_fsg; | 4085 | fsg = the_fsg; |
4083 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) { | 4086 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
4084 | fsg_free(fsg); | 4087 | fsg_free(fsg); |
4085 | return rc; | 4088 | return rc; |
4086 | } | ||
4087 | set_bit(REGISTERED, &fsg->atomic_bitflags); | ||
4088 | |||
4089 | /* Tell the thread to start working */ | ||
4090 | wake_up_process(fsg->thread_task); | ||
4091 | return 0; | ||
4092 | } | 4089 | } |
4093 | module_init(fsg_init); | 4090 | module_init(fsg_init); |
4094 | 4091 | ||