Browse Source

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>
Mike Isely 17 years ago
parent
commit
97f26ff604
1 changed files with 10 additions and 1 deletions
  1. 10 1
      drivers/media/video/pvrusb2/pvrusb2-hdw.c

+ 10 - 1
drivers/media/video/pvrusb2/pvrusb2-hdw.c

@@ -1854,10 +1854,19 @@ int pvr2_hdw_initialize(struct pvr2_hdw *hdw,
 			void *callback_data)
 {
 	LOCK_TAKE(hdw->big_lock); do {
+		if (hdw->flag_disconnected) {
+			/* Handle a race here: If we're already
+			   disconnected by this point, then give up.  If we
+			   get past this then we'll remain connected for
+			   the duration of initialization since the entire
+			   initialization sequence is now protected by the
+			   big_lock. */
+			break;
+		}
 		hdw->state_data = callback_data;
 		hdw->state_func = callback_func;
+		pvr2_hdw_setup(hdw);
 	} while (0); LOCK_GIVE(hdw->big_lock);
-	pvr2_hdw_setup(hdw);
 	return hdw->flag_init_ok;
 }