From 42632805f5f2d754567e9fff5298d14a40680d71 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 28 Sep 2012 14:36:08 +0300 Subject: Bluetooth: btmrvl: Correct num_block name Make code readable by correcting name from buf_block_len to num_blocks since it represent number of blocks; NOT a length of a block buffer. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_sdio.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 3f4bfc814dc..645b42e143f 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -492,7 +492,7 @@ done: static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) { u16 buf_len = 0; - int ret, buf_block_len, blksz; + int ret, num_blocks, blksz; struct sk_buff *skb = NULL; u32 type; u8 *payload = NULL; @@ -514,18 +514,17 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) } blksz = SDIO_BLOCK_SIZE; - buf_block_len = (buf_len + blksz - 1) / blksz; + num_blocks = (buf_len + blksz - 1) / blksz; if (buf_len <= SDIO_HEADER_LEN - || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { + || (num_blocks * blksz) > ALLOC_BUF_SIZE) { BT_ERR("invalid packet length: %d", buf_len); ret = -EINVAL; goto exit; } /* Allocate buffer */ - skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN, - GFP_ATOMIC); + skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC); if (skb == NULL) { BT_ERR("No free skb"); goto exit; @@ -541,7 +540,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) payload = skb->data; ret = sdio_readsb(card->func, payload, card->ioport, - buf_block_len * blksz); + num_blocks * blksz); if (ret < 0) { BT_ERR("readsb failed: %d", ret); ret = -EIO; @@ -590,7 +589,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) default: BT_ERR("Unknown packet type:%d", type); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, - blksz * buf_block_len); + blksz * num_blocks); kfree_skb(skb); skb = NULL; -- cgit v1.2.3 From e678bad515f06d3ca5def3a28aa21a5aeb51cf30 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 28 Sep 2012 14:36:09 +0300 Subject: Bluetooth: btmrvl: Use DIV_ROUND_UP macro The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 645b42e143f..ec5c45672f1 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -514,7 +514,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) } blksz = SDIO_BLOCK_SIZE; - num_blocks = (buf_len + blksz - 1) / blksz; + num_blocks = DIV_ROUND_UP(buf_len, blksz); if (buf_len <= SDIO_HEADER_LEN || (num_blocks * blksz) > ALLOC_BUF_SIZE) { -- cgit v1.2.3 From 9cb23dd4b6361538eeca33f463b649e8939edde1 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 28 Sep 2012 14:36:10 +0300 Subject: Bluetooth: btmrvl: Fix skb buffer overflow Add extra check to avoid skb buffer overflow. Fixes crash below: [ 101.030427] ------------[ cut here ]------------ [ 101.030459] kernel BUG at net/core/skbuff.c:127! [ 101.030486] invalid opcode: 0000 [#1] SMP ... [ 101.030806] Pid: 2010, comm: btmrvl_main_ser Not tainted 3.5.0+ #80 Laptop [ 101.030859] EIP: 0060:[] EFLAGS: 00010282 CPU: 0 [ 101.030894] EIP is at skb_put+0x99/0xa0 [ 101.030919] EAX: 00000080 EBX: f129380b ECX: ef923540 EDX: 00000001 [ 101.030956] ESI: f00a4000 EDI: 00001003 EBP: ed4a5efc ESP: ed4a5ecc [ 101.030992] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 101.031024] CR0: 8005003b CR2: 08fca014 CR3: 30960000 CR4: 000407f0 [ 101.031062] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [ 101.031100] DR6: ffff0ff0 DR7: 00000400 [ 101.031125] Process btmrvl_main_ser (pid: 2010, ti=ed4a4000 task=ef923540 task.ti=ed4a4000) [ 101.031174] Stack: [ 101.031188] c18126f8 c1651938 f853f8d2 00001003 00001003 f1292800 f1292808 f129380b [ 101.031250] f1292940 f00a4000 eddb1280 efc0f9c0 ed4a5f44 f853f8d2 00000040 00000000 [ 101.031312] ef923540 c15ee096 ef923540 eddb12d4 00000004 f00a4000 00000040 00000000 [ 101.031376] Call Trace: [ 101.031396] [] ? btmrvl_sdio_process_int_status+0x272/0x3d0 [btmrvl_sdio] [ 101.031444] [] btmrvl_sdio_process_int_status+0x272/0x3d0 [btmrvl_sdio] [ 101.031488] [] ? _raw_spin_unlock_irqrestore+0x36/0x70 [ 101.031526] [] btmrvl_service_main_thread+0x244/0x300 [btmrvl] [ 101.031568] [] ? btmrvl_sdio_poll_card_status.isra.6.constprop.7+0x90/0x90 [btmrvl_sdio] [ 101.031619] [] ? try_to_wake_up+0x270/0x270 [ 101.031648] [] ? btmrvl_process_event+0x3b0/0x3b0 [btmrvl] [ 101.031686] [] kthread+0x7d/0x90 [ 101.031713] [] ? flush_kthread_work+0x150/0x150 [ 101.031745] [] kernel_thread_helper+0x6/0x10 ... [ 101.032008] EIP: [] skb_put+0x99/0xa0 SS:ESP 0068:ed4a5ecc [ 101.056125] ---[ end trace a0bd01d1a9a796c8 ]--- Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_sdio.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index ec5c45672f1..1896e916ff7 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -552,7 +552,16 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) */ buf_len = payload[0]; - buf_len |= (u16) payload[1] << 8; + buf_len |= payload[1] << 8; + buf_len |= payload[2] << 16; + + if (buf_len > blksz * num_blocks) { + BT_ERR("Skip incorrect packet: hdrlen %d buffer %d", + buf_len, blksz * num_blocks); + ret = -EIO; + goto exit; + } + type = payload[3]; switch (type) { -- cgit v1.2.3 From 78c1b8e822a0bcf9655a0da3633137b51e17f068 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 10 Oct 2012 17:41:33 +0300 Subject: Bluetooth: btmrv: Use %*ph specifier instead of print_hex_dump_bytes Use standard print specifier and remove print_hex_dump_bytes call. Makes output more sensible: ... [18809.401218] 00000000: 0b 00 00 fe 5b fc 01 f2 00 00 00 ....[...... ... would be changed to ... [18809.401218] Bluetooth: hex: 0b 00 00 fe 5b fc 01 f2 00 00 00 ... Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_sdio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 1896e916ff7..9959d4cb23d 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -597,8 +597,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) default: BT_ERR("Unknown packet type:%d", type); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, - blksz * num_blocks); + BT_ERR("hex: %*ph", blksz * num_blocks, payload); kfree_skb(skb); skb = NULL; @@ -857,8 +856,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, if (ret < 0) { i++; BT_ERR("i=%d writesb failed: %d", i, ret); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - payload, nb); + BT_ERR("hex: %*ph", nb, payload); ret = -EIO; if (i > MAX_WRITE_IOMEM_RETRY) goto exit; -- cgit v1.2.3 From 1ee3ff6110c16acfc915a79b1e3feb5013c41e75 Mon Sep 17 00:00:00 2001 From: Jeff Cook Date: Fri, 9 Nov 2012 16:39:48 -0700 Subject: Bluetooth: Add support for BCM20702A0 [0b05, 17b5] Vendor-specific ID for BCM20702A0. Support for bluetooth over Asus Wi-Fi GO!, included with Asus P8Z77-V Deluxe. T: Bus=07 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0b05 ProdID=17b5 Rev=01.12 S: Manufacturer=Broadcom Corp S: Product=BCM20702A0 S: SerialNumber=94DBC98AC113 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) Cc: stable@vger.kernel.org Signed-off-by: Jeff Cook Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btusb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index debda27df9b..5693b9b3147 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ + { USB_DEVICE(0x0b05, 0x17b5) }, { USB_DEVICE(0x04ca, 0x2003) }, { USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x413c, 0x8197) }, -- cgit v1.2.3