From 9cb23dd4b6361538eeca33f463b649e8939edde1 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 28 Sep 2012 14:36:10 +0300 Subject: [PATCH] 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(-) diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index ec5c456..1896e91 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) { -- 2.7.4