Skip to contentSkip to conversation

hci_usb.h: fix hard-to-trigger race

PATCH Applied [email protected] 5 participants 8 messages Apr 18, 2008 – Apr 19, 2008 2 messages not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 3/3 hci_usb.h: fix hard-to-trigger race

From: Pavel Machek <[email protected]>

If someone tries to _urb_unlink while _urb_queue_head is running, he'll see _urb->queue == NULL and fail to do any locking. Prevent that from happening by strategically placed barriers.

---

 drivers/bluetooth/hci_usb.h |   21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/bluetooth/hci_usb.h renamed from drivers/bluetooth/hci_usb.h~hci_usbh-fix-hard-to-trigger-race +13 -8
diff -puN drivers/bluetooth/hci_usb.h~hci_usbh-fix-hard-to-trigger-race drivers/bluetooth/hci_usb.h
@@ -70,7 +70,8 @@ static inline void _urb_queue_head(struc
 {
 	unsigned long flags;
 	spin_lock_irqsave(&q->lock, flags);
-	list_add(&_urb->list, &q->head); _urb->queue = q;
+	/* _urb_unlink needs to know which spinlock to use, thus mb(). */
+	_urb->queue = q; mb(); list_add(&_urb->list, &q->head);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
@@ -78,19 +79,23 @@ static inline void _urb_queue_tail(struc
 {
 	unsigned long flags;
 	spin_lock_irqsave(&q->lock, flags);
-	list_add_tail(&_urb->list, &q->head); _urb->queue = q;
+	/* _urb_unlink needs to know which spinlock to use, thus mb(). */
+	_urb->queue = q; mb(); list_add_tail(&_urb->list, &q->head);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
 static inline void _urb_unlink(struct _urb *_urb)
 {
-	struct _urb_queue *q = _urb->queue;
+	struct _urb_queue *q;
 	unsigned long flags;
-	if (q) {
-		spin_lock_irqsave(&q->lock, flags);
-		list_del(&_urb->list); _urb->queue = NULL;
-		spin_unlock_irqrestore(&q->lock, flags);
-	}
+
+	mb();
+	q = _urb->queue;
+	/* If q is NULL, it will die at easy-to-debug NULL pointer dereference.
+	   No need to BUG(). */
+	spin_lock_irqsave(&q->lock, flags);
+	list_del(&_urb->list); _urb->queue = NULL;
+	spin_unlock_irqrestore(&q->lock, flags);
 }
 
 struct hci_usb {

_

maintainer
#1 lore raw

Hi Andrew,

Quoted 5 lines

From: Pavel Machek <[email protected]>

If someone tries to _urb_unlink while _urb_queue_head is running, he'll see _urb->queue == NULL and fail to do any locking. Prevent that from happening by strategically placed barriers.

let me repeat this, the hci_usb driver is not worth fixing. Doing our own URB handling is a bad idea. The btusb driver should fix all of this. Only exception is that it is missing all the quirks, but that was me being lazy.

Regards

Marcel

A message that is not in the archive (sent off-list or not yet received): 55DEC459-2D49-4366-88CC-21E9CA6783DC-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org

#3 lore raw
Quoted 10 lines · On Fri, 18 Apr 2008 23:10:12 +0200 Marcel Holtmann…

Hi Andrew,

Quoted 7 lines

From: Pavel Machek <[email protected]>

If someone tries to _urb_unlink while _urb_queue_head is running, he'll see
_urb->queue == NULL and fail to do any locking. Prevent that from happening
by strategically placed barriers.

Quoted 5 lines

let me repeat this, the hci_usb driver is not worth fixing. Doing our own URB handling is a bad idea. The btusb driver should fix all of this. Only exception is that it is missing all the quirks, but that was me being lazy.

ok... But as long as the old code is buildable and installable, we should fix bugs in it?

A message that is not in the archive (sent off-list or not yet received): 20080418142153.4e0eb83b.akpm-de/[email protected]

#5 lore raw

From: Andrew Morton <akpm-de/[email protected]>
Date: Fri, 18 Apr 2008 14:21:53 -0700

Quoted 13 lines
Quoted 10 lines · On Fri, 18 Apr 2008 23:10:12 +0200 Marcel Holtmann…

Hi Andrew,

Quoted 7 lines

From: Pavel Machek <[email protected]>

If someone tries to _urb_unlink while _urb_queue_head is running, he'll see
_urb->queue == NULL and fail to do any locking. Prevent that from happening
by strategically placed barriers.

Quoted 8 lines
Quoted 5 lines

let me repeat this, the hci_usb driver is not worth fixing. Doing our own URB handling is a bad idea. The btusb driver should fix all of this. Only exception is that it is missing all the quirks, but that was me being lazy.

ok... But as long as the old code is buildable and installable, we should fix bugs in it?

Yep.

maintainer
#6 lore raw
In reply to Andrew Morton

Hi Andrew,

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

If someone tries to _urb_unlink while _urb_queue_head is running, he'll see
_urb->queue == NULL and fail to do any locking. Prevent that from happening
by strategically placed barriers.

Quoted 8 lines
Quoted 5 lines

let me repeat this, the hci_usb driver is not worth fixing. Doing our own URB handling is a bad idea. The btusb driver should fix all of this. Only exception is that it is missing all the quirks, but that was me being lazy.

ok... But as long as the old code is buildable and installable, we should fix bugs in it?

I am okay with it and happy to accept any fixes, but to be quite honest, that this driver still works is in some cases pure luck. Doing the URB handling by ourself is really simply plain work. No excuses here and parts of it is my fault. I know that. Hence I started a new implementation from scratch.

Regards

Marcel

#7 lore raw

PATCH 1/1 document hci_usb as broken

Hi!

Quoted 8 lines
Quoted 2 lines

ok... But as long as the old code is buildable and installable, we should fix bugs in it?

I am okay with it and happy to accept any fixes, but to be quite honest, that this driver still works is in some cases pure luck. Doing the URB handling by ourself is really simply plain work. No excuses here and parts of it is my fault. I know that. Hence I started a new implementation from scratch.

Ok, so I guess this is good idea... (I'd prefer previous race patch to still be applied; but driver is broken even with that fix...)

I thought about adding && BROKEN to Kconfig...

---

hci_usb is fatally broken, document it as such.

drivers/bluetooth/Kconfig +4 -1
index 075598e..20d9279 100644
@@ -3,13 +3,16 @@ menu "Bluetooth device drivers"
 	depends on BT
 
 config BT_HCIUSB
-	tristate "HCI USB driver"
+	tristate "HCI USB driver (dangerous, use alternate driver below)"
 	depends on USB
 	help
 	  Bluetooth HCI USB driver.
 	  This driver is required if you want to use Bluetooth devices with
 	  USB interface.
 
+	  Unfortunately, locking in this driver is fatally broken; it will
+	  corrupt memory on surprise disconnect and during resume.
+
 	  Say Y here to compile support for Bluetooth USB devices into the
 	  kernel or say M to compile it as module (hci_usb).
 
drivers/bluetooth/hci_usb.c +16 -2
index 192522e..6cc96b4 100644
@@ -1,8 +1,22 @@
-/* 
+/*
+
+    This driver has fatally broken locking.
+
+    DO NOT USE.
+
+    See btusb.c for cleaner / shorter / actually working driver.
+
+
+
+
+
+
+
+
+ 
    HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
    Copyright (C) 2000-2001 Qualcomm Incorporated
    Written 2000,2001 by Maxim Krasnyansky <[email protected]>
-
    Copyright (C) 2003 Maxim Krasnyansky <[email protected]>
 
    This program is free software; you can redistribute it and/or modify
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
maintainer
#8 lore raw

Re: [patch] document hci_usb as broken

Hi Pavel,

Quoted 39 lines
Quoted 8 lines
Quoted 2 lines

ok... But as long as the old code is buildable and installable, we should fix bugs in it?

I am okay with it and happy to accept any fixes, but to be quite honest, that this driver still works is in some cases pure luck. Doing the URB handling by ourself is really simply plain work. No excuses here and parts of it is my fault. I know that. Hence I started a new implementation from scratch.

Ok, so I guess this is good idea... (I'd prefer previous race patch to still be applied; but driver is broken even with that fix...)

I thought about adding && BROKEN to Kconfig...

---

hci_usb is fatally broken, document it as such.

drivers/bluetooth/Kconfig +0 -0
index 075598e..20d9279 100644
@@ -3,13 +3,16 @@ menu "Bluetooth device drivers"
 	depends on BT
 

config BT_HCIUSB

drivers/bluetooth/Kconfig +1 -1
-	tristate "HCI USB driver"
+	tristate "HCI USB driver (dangerous, use alternate driver below)"

depends on USB
help
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with USB interface.

drivers/bluetooth/Kconfig +3 -0
+	  Unfortunately, locking in this driver is fatally broken; it will
+	  corrupt memory on surprise disconnect and during resume.
+
Quoted 2 lines

Say Y here to compile support for Bluetooth USB devices into the kernel or say M to compile it as module (hci_usb).

this would be fine with me. Acked-by: Marcel Holtmann <[email protected]>

drivers/bluetooth/hci_usb.c line 7

Quoted 13 lines
drivers/bluetooth/hci_usb.c +7 -1
index 192522e..6cc96b4 100644
@@ -1,8 +1,22 @@
-/*
+/*
+
+    This driver has fatally broken locking.
+
+    DO NOT USE.
+
+    See btusb.c for cleaner / shorter / actually working driver.

NAK to this hunk. Not needed. The Kconfig help is enough.

Regards

Marcel

#9 lore raw

Re: [patch] document hci_usb as broken

Hi!

Quoted 23 lines
Quoted 18 lines

index 075598e..20d9279 100644

drivers/bluetooth/Kconfig +0 -0
@@ -3,13 +3,16 @@ menu "Bluetooth device drivers"
 	depends on BT
 

config BT_HCIUSB

drivers/bluetooth/Kconfig +1 -1
-	tristate "HCI USB driver"
+	tristate "HCI USB driver (dangerous, use alternate driver below)"

depends on USB
help
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with USB interface.

drivers/bluetooth/Kconfig +3 -0
+	  Unfortunately, locking in this driver is fatally broken; it will
+	  corrupt memory on surprise disconnect and during resume.
+
Quoted 2 lines

Say Y here to compile support for Bluetooth USB devices into the kernel or say M to compile it as module (hci_usb).

this would be fine with me. Acked-by: Marcel Holtmann <[email protected]>

Quoted 15 lines

drivers/bluetooth/hci_usb.c line 7

Quoted 13 lines
drivers/bluetooth/hci_usb.c +7 -1
index 192522e..6cc96b4 100644
@@ -1,8 +1,22 @@
-/*
+/*
+
+    This driver has fatally broken locking.
+
+    DO NOT USE.
+
+    See btusb.c for cleaner / shorter / actually working driver.

NAK to this hunk. Not needed. The Kconfig help is enough.

Developers trying to debug hci_usb problems will nor see the help text, since they probably have it enabled in their .config already and will not be asked again...

Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html