diff options
author | Mike Isely <isely@pobox.com> | 2008-04-07 01:22:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:48 -0400 |
commit | 97f26ff6049a7fff5460cebe392ad1d699dc434c (patch) | |
tree | 8baf83788707e1488918ba00c7430b6f7b0a9d45 /drivers/media | |
parent | e5be15c63804e05b5a94197524023702a259e308 (diff) |
V4L/DVB (7712): pvrusb2: Close connect/disconnect race
If a disconnect happens before initialization is completed, the
pvrusb2 driver can accidentally touch dangling pointers. The whole
initialization function must be protected by the big_lock, and once
inside that lock, the initialization function should abort if it is
discovered that a disconnect has already taken place.
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 4f6bb58ca5fc..f907a56c587d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -1854,10 +1854,19 @@ int pvr2_hdw_initialize(struct pvr2_hdw *hdw, | |||
1854 | void *callback_data) | 1854 | void *callback_data) |
1855 | { | 1855 | { |
1856 | LOCK_TAKE(hdw->big_lock); do { | 1856 | LOCK_TAKE(hdw->big_lock); do { |
1857 | if (hdw->flag_disconnected) { | ||
1858 | /* Handle a race here: If we're already | ||
1859 | disconnected by this point, then give up. If we | ||
1860 | get past this then we'll remain connected for | ||
1861 | the duration of initialization since the entire | ||
1862 | initialization sequence is now protected by the | ||
1863 | big_lock. */ | ||
1864 | break; | ||
1865 | } | ||
1857 | hdw->state_data = callback_data; | 1866 | hdw->state_data = callback_data; |
1858 | hdw->state_func = callback_func; | 1867 | hdw->state_func = callback_func; |
1868 | pvr2_hdw_setup(hdw); | ||
1859 | } while (0); LOCK_GIVE(hdw->big_lock); | 1869 | } while (0); LOCK_GIVE(hdw->big_lock); |
1860 | pvr2_hdw_setup(hdw); | ||
1861 | return hdw->flag_init_ok; | 1870 | return hdw->flag_init_ok; |
1862 | } | 1871 | } |
1863 | 1872 | ||