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 | |
| 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>
| -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 | ||
