aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-04-07 01:22:43 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:48 -0400
commit97f26ff6049a7fff5460cebe392ad1d699dc434c (patch)
tree8baf83788707e1488918ba00c7430b6f7b0a9d45 /drivers/media/video/pvrusb2
parente5be15c63804e05b5a94197524023702a259e308 (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/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c11
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