Skip to contentSkip to conversation

Pull request: bluetooth-2.6 2010-02-05

PATCH New Marcel Holtmann 2 participants 10 messages Feb 5, 2010 – Feb 9, 2010

Subsystems (4)
lore
Share & tools
lore

Marcel Holtmann

author maintainer
#0 lore raw

Hi Dave,

here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.

The important one are the fix for the sleeping function call in the RFCOMM timer that show up with certain hardware (not all of them) and also the fix for double release of the underlaying L2CAP session.

With the HID subsystem changes that turns it into a proper bus, the HIDP code ended up with a potential case where we access userspace memory out of the scop of its ioctl() command. Fix this by just keeping a copy of the HID report descriptor around. The HID subsystem will need that anyway.

The rest are some SCO/eSCO audio setup fixes with broken hardware and closing a memory leak in the Marvell driver.

Regards

Marcel

Please pull from

git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git master

This will update the following files:

 drivers/bluetooth/btmrvl_sdio.c |    1 +
 net/bluetooth/hci_conn.c        |    3 ++
 net/bluetooth/hci_event.c       |    1 +
 net/bluetooth/hidp/core.c       |   49 +++++++++++++++++++--------------------
 net/bluetooth/hidp/hidp.h       |    4 ++-
 net/bluetooth/rfcomm/core.c     |    8 ++++-
 6 files changed, 38 insertions(+), 28 deletions(-)

through these ChangeSets:

Marcel Holtmann (1):
Bluetooth: Fix sleeping function in RFCOMM within invalid context

Michael Poole (1):
Bluetooth: Keep a copy of each HID device's report descriptor

Nick Pelly (3):
Bluetooth: Fallback eSCO to SCO on error 0x1a (Unsupported Remote
Bluetooth: Do not call rfcomm_session_put() for RFCOMM UA on closed
Bluetooth: Enter active mode before establishing a SCO link.

Yoichi Yuasa (1):
Bluetooth: Fix memory leak in Marvell BT-over-SDIO driver

author maintainer
#1 lore raw

PATCH 1/6 Bluetooth: Fallback eSCO to SCO on error 0x1a (Unsupported Remote Feature)

From: Nick Pelly <[email protected]>

General Motors carkits that use LGE BT chipsets return this error code when an eSCO is attempted, despite advertising eSCO support.

2009-08-13 14:41:39.755518 < HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17
   handle 1 voice setting 0x0060
2009-08-13 14:41:39.757563 > HCI Event: Command Status (0x0f) plen 4
   Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1
2009-08-13 14:41:39.789484 > HCI Event: Synchronous Connect Complete (0x2c) plen 17
   status 0x1a handle 257 bdaddr 00:1E:B2:23:5E:B3 type eSCO
   Error: Unsupported Remote Feature / Unsupported LMP Feature
---
 net/bluetooth/hci_event.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
net/bluetooth/hci_event.c +1 -0
index 28517ba..592da5c 100644
@@ -1699,6 +1699,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
 		break;
 
 	case 0x1c:	/* SCO interval rejected */
+	case 0x1a:	/* Unsupported Remote Feature */
 	case 0x1f:	/* Unspecified error */
 		if (conn->out && conn->attempt < 2) {
 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
Signature · 1 line
1.6.6
author maintainer
#2 lore raw

PATCH 2/6 Bluetooth: Fix sleeping function in RFCOMM within invalid context

With the commit 9e726b17422bade75fba94e625cd35fd1353e682 the rfcomm_session_put() gets accidentially called from a timeout callback and results in this:

BUG: sleeping function called from invalid context at net/core/sock.c:1897
in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper
Pid: 0, comm: swapper Tainted: P           2.6.32 #31
Call Trace:
 <IRQ>  [<ffffffff81036455>] __might_sleep+0xf8/0xfa
 [<ffffffff8138ef1d>] lock_sock_nested+0x29/0xc4
 [<ffffffffa03921b3>] lock_sock+0xb/0xd [l2cap]
 [<ffffffffa03948e6>] l2cap_sock_shutdown+0x1c/0x76 [l2cap]
 [<ffffffff8106adea>] ? clockevents_program_event+0x75/0x7e
 [<ffffffff8106bea2>] ? tick_dev_program_event+0x37/0xa5
 [<ffffffffa0394967>] l2cap_sock_release+0x27/0x67 [l2cap]
 [<ffffffff8138c971>] sock_release+0x1a/0x67
 [<ffffffffa03d2492>] rfcomm_session_del+0x34/0x53 [rfcomm]
 [<ffffffffa03d24c5>] rfcomm_session_put+0x14/0x16 [rfcomm]
 [<ffffffffa03d28b4>] rfcomm_session_timeout+0xe/0x1a [rfcomm]
 [<ffffffff810554a8>] run_timer_softirq+0x1e2/0x29a
 [<ffffffffa03d28a6>] ? rfcomm_session_timeout+0x0/0x1a [rfcomm]
 [<ffffffff8104e0f6>] __do_softirq+0xfe/0x1c5
 [<ffffffff8100e8ce>] ? timer_interrupt+0x1a/0x21
 [<ffffffff8100cc4c>] call_softirq+0x1c/0x28
 [<ffffffff8100e05b>] do_softirq+0x33/0x6b
 [<ffffffff8104daf6>] irq_exit+0x36/0x85
 [<ffffffff8100d7a9>] do_IRQ+0xa6/0xbd
 [<ffffffff8100c493>] ret_from_intr+0x0/0xa
 <EOI>  [<ffffffff812585b3>] ? acpi_idle_enter_bm+0x269/0x294
 [<ffffffff812585a9>] ? acpi_idle_enter_bm+0x25f/0x294
 [<ffffffff81373ddc>] ? cpuidle_idle_call+0x97/0x107
 [<ffffffff8100aca0>] ? cpu_idle+0x53/0xaa
 [<ffffffff81429006>] ? rest_init+0x7a/0x7c
 [<ffffffff8177bc8c>] ? start_kernel+0x389/0x394
 [<ffffffff8177b29c>] ? x86_64_start_reservations+0xac/0xb0
 [<ffffffff8177b384>] ? x86_64_start_kernel+0xe4/0xeb

To fix this, the rfcomm_session_put() needs to be moved out of rfcomm_session_timeout() into rfcomm_process_sessions(). In that context it is perfectly fine to sleep and disconnect the socket.

---
 net/bluetooth/rfcomm/core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/bluetooth/rfcomm/core.c +1 -1
index fc5ee32..2b50637 100644
@@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg)
 	BT_DBG("session %p state %ld", s, s->state);
 
 	set_bit(RFCOMM_TIMED_OUT, &s->flags);
-	rfcomm_session_put(s);
 	rfcomm_schedule(RFCOMM_SCHED_TIMEO);
 }
 
@@ -1920,6 +1919,7 @@ static inline void rfcomm_process_sessions(void)
 		if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
 			s->state = BT_DISCONN;
 			rfcomm_send_disc(s, 0);
+			rfcomm_session_put(s);
 			continue;
 		}
 
Signature · 1 line
1.6.6
author maintainer
#3 lore raw

PATCH 3/6 Bluetooth: Do not call rfcomm_session_put() for RFCOMM UA on closed socket

From: Nick Pelly <[email protected]>

When processing a RFCOMM UA frame when the socket is closed and we were not the RFCOMM initiator would cause rfcomm_session_put() to be called twice during rfcomm_process_rx(). This would cause a kernel panic in rfcomm_session_close() then.

This could be easily reproduced during disconnect with devices such as Motorola H270 that send RFCOMM UA followed quickly by L2CAP disconnect request. This trace for this looks like:

2009-09-21 17:22:37.788895 < ACL data: handle 1 flags 0x02 dlen 8
   L2CAP(d): cid 0x0041 len 4 [psm 3]
     RFCOMM(s): DISC: cr 0 dlci 20 pf 1 ilen 0 fcs 0x7d
2009-09-21 17:22:37.906204 > HCI Event: Number of Completed Packets (0x13) plen 5
   handle 1 packets 1
2009-09-21 17:22:37.933090 > ACL data: handle 1 flags 0x02 dlen 8
   L2CAP(d): cid 0x0040 len 4 [psm 3]
     RFCOMM(s): UA: cr 0 dlci 20 pf 1 ilen 0 fcs 0x57
2009-09-21 17:22:38.636764 < ACL data: handle 1 flags 0x02 dlen 8
   L2CAP(d): cid 0x0041 len 4 [psm 3]
     RFCOMM(s): DISC: cr 0 dlci 0 pf 1 ilen 0 fcs 0x9c
2009-09-21 17:22:38.744125 > HCI Event: Number of Completed Packets (0x13) plen 5
   handle 1 packets 1
2009-09-21 17:22:38.763687 > ACL data: handle 1 flags 0x02 dlen 8
   L2CAP(d): cid 0x0040 len 4 [psm 3]
     RFCOMM(s): UA: cr 0 dlci 0 pf 1 ilen 0 fcs 0xb6
2009-09-21 17:22:38.783554 > ACL data: handle 1 flags 0x02 dlen 12
   L2CAP(s): Disconn req: dcid 0x0040 scid 0x0041

Avoid calling rfcomm_session_put() twice by skipping this call in rfcomm_recv_ua() if the socket is closed.

---
 net/bluetooth/rfcomm/core.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
net/bluetooth/rfcomm/core.c +5 -1
index 2b50637..89f4a59 100644
@@ -1150,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
 			break;
 
 		case BT_DISCONN:
-			rfcomm_session_put(s);
+			/* When socket is closed and we are not RFCOMM
+			 * initiator rfcomm_process_rx already calls
+			 * rfcomm_session_put() */
+			if (s->sock->sk->sk_state != BT_CLOSED)
+				rfcomm_session_put(s);
 			break;
 		}
 	}
Signature · 1 line
1.6.6
author maintainer
#4 lore raw

PATCH 4/6 Bluetooth: Fix memory leak in Marvell BT-over-SDIO driver

From: Yoichi Yuasa <[email protected]>

---
 drivers/bluetooth/btmrvl_sdio.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/bluetooth/btmrvl_sdio.c +1 -0
index f36defa..57d965b 100644
@@ -808,6 +808,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
 
 exit:
 	sdio_release_host(card->func);
+	kfree(tmpbuf);
 
 	return ret;
 }
Signature · 1 line
1.6.6
author maintainer
#5 lore raw

PATCH 5/6 Bluetooth: Enter active mode before establishing a SCO link.

From: Nick Pelly <[email protected]>

When in sniff mode with a long interval time (1.28s) it can take 4+ seconds to establish a SCO link. Fix by requesting active mode before requesting SCO connection. This improves SCO setup time to ~500ms.

Bluetooth headsets that use a long interval time, and exhibit the long SCO connection time include Motorola H790, HX1 and H17. They have a CSR 2.1 chipset.

Verified this behavior and fix with host Bluetooth chipsets: BCM4329 and TI1271.

2009-10-13 14:17:46.183722 > HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 1 mode 0x02 interval 2048
    Mode: Sniff
2009-10-13 14:17:53.436285 < HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17
    handle 1 voice setting 0x0060
2009-10-13 14:17:53.445593 > HCI Event: Command Status (0x0f) plen 4
    Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1
2009-10-13 14:17:57.788855 > HCI Event: Synchronous Connect Complete 0x2c) plen 17
    status 0x00 handle 257 bdaddr 00:1A:0E:F1:A4:7F type eSCO
    Air mode: CVSD
---
 net/bluetooth/hci_conn.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
net/bluetooth/hci_conn.c +3 -0
index b7c4224..b10e3cd 100644
@@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
 
 	if (acl->state == BT_CONNECTED &&
 			(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+		acl->power_save = 1;
+		hci_conn_enter_active_mode(acl);
+
 		if (lmp_esco_capable(hdev))
 			hci_setup_sync(sco, acl->handle);
 		else
Signature · 1 line
1.6.6
author maintainer
#6 lore raw

PATCH 6/6 Bluetooth: Keep a copy of each HID device's report descriptor

From: Michael Poole <[email protected]>

The report descriptor is read by user space (via the Service Discovery Protocol), so it is only available during the ioctl to connect. However, the HID probe function that needs the descriptor might not be called until a specific module is loaded. Keep a copy of the descriptor so it is available for later use.

---
 net/bluetooth/hidp/core.c |   49 ++++++++++++++++++++++-----------------------
 net/bluetooth/hidp/hidp.h |    4 ++-
 2 files changed, 27 insertions(+), 26 deletions(-)
net/bluetooth/hidp/core.c +24 -25
index 6cf526d..fc6ec1e 100644
@@ -703,29 +703,9 @@ static void hidp_close(struct hid_device *hid)
 static int hidp_parse(struct hid_device *hid)
 {
 	struct hidp_session *session = hid->driver_data;
-	struct hidp_connadd_req *req = session->req;
-	unsigned char *buf;
-	int ret;
-
-	buf = kmalloc(req->rd_size, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	if (copy_from_user(buf, req->rd_data, req->rd_size)) {
-		kfree(buf);
-		return -EFAULT;
-	}
-
-	ret = hid_parse_report(session->hid, buf, req->rd_size);
-
-	kfree(buf);
-
-	if (ret)
-		return ret;
-
-	session->req = NULL;
 
-	return 0;
+	return hid_parse_report(session->hid, session->rd_data,
+			session->rd_size);
 }
 
 static int hidp_start(struct hid_device *hid)
@@ -770,12 +750,24 @@ static int hidp_setup_hid(struct hidp_session *session,
 	bdaddr_t src, dst;
 	int err;
 
+	session->rd_data = kzalloc(req->rd_size, GFP_KERNEL);
+	if (!session->rd_data)
+		return -ENOMEM;
+
+	if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) {
+		err = -EFAULT;
+		goto fault;
+	}
+	session->rd_size = req->rd_size;
+
 	hid = hid_allocate_device();
-	if (IS_ERR(hid))
-		return PTR_ERR(hid);
+	if (IS_ERR(hid)) {
+		err = PTR_ERR(hid);
+		goto fault;
+	}
 
 	session->hid = hid;
-	session->req = req;
+
 	hid->driver_data = session;
 
 	baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
@@ -806,6 +798,10 @@ failed:
 	hid_destroy_device(hid);
 	session->hid = NULL;
 
+fault:
+	kfree(session->rd_data);
+	session->rd_data = NULL;
+
 	return err;
 }
 
@@ -900,6 +896,9 @@ unlink:
 		session->hid = NULL;
 	}
 
+	kfree(session->rd_data);
+	session->rd_data = NULL;
+
 purge:
 	skb_queue_purge(&session->ctrl_transmit);
 	skb_queue_purge(&session->intr_transmit);
net/bluetooth/hidp/hidp.h +3 -1
index faf3d74..a4e215d 100644
@@ -154,7 +154,9 @@ struct hidp_session {
 	struct sk_buff_head ctrl_transmit;
 	struct sk_buff_head intr_transmit;
 
-	struct hidp_connadd_req *req;
+	/* Report descriptor */
+	__u8 *rd_data;
+	uint rd_size;
 };
 
 static inline void hidp_schedule(struct hidp_session *session)
Signature · 1 line
1.6.6
maintainer
#7 lore raw
In reply to Marcel Holtmann

From: Marcel Holtmann <[email protected]>
Date: Fri, 5 Feb 2010 12:05:33 -0800

Quoted 2 lines

here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.

Man, I live in Seattle and I still never get invited to these cool events ;-)

Quoted 12 lines

The important one are the fix for the sleeping function call in the RFCOMM timer that show up with certain hardware (not all of them) and also the fix for double release of the underlaying L2CAP session.

With the HID subsystem changes that turns it into a proper bus, the HIDP code ended up with a potential case where we access userspace memory out of the scop of its ioctl() command. Fix this by just keeping a copy of the HID report descriptor around. The HID subsystem will need that anyway.

The rest are some SCO/eSCO audio setup fixes with broken hardware and closing a memory leak in the Marvell driver.

...

Quoted 3 lines

Please pull from

git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git master

Pulled, thanks!

author maintainer
#8 lore raw

Hi Dave,

Quoted 5 lines
Quoted 2 lines

here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.

Man, I live in Seattle and I still never get invited to these cool events ;-)

I wouldn't call them cool actually. It is a stressful week of non-stop testing against other Bluetooth stacks and products. Also they are covered under an NDA since some companies are testing with prototypes.

Regards

Marcel

maintainer
#9 lore raw

From: Marcel Holtmann <[email protected]>
Date: Tue, 09 Feb 2010 16:52:04 +0100

Quoted 11 lines

Hi Dave,

Quoted 5 lines
Quoted 2 lines

here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.

Man, I live in Seattle and I still never get invited to these cool events ;-)

I wouldn't call them cool actually. It is a stressful week of non-stop testing against other Bluetooth stacks and products. Also they are covered under an NDA since some companies are testing with prototypes.

I guess I need to find a better emoticon to use for sarcasm.