aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@nokia.com>2010-03-19 04:26:28 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-03-21 00:49:36 -0400
commitc2c77ec83bdad17fb688557b5b3fdc36661dd1c6 (patch)
treed213eafcc44b8c8fdc5f8c61d65acb6ef5de5e4e
parentaef7d97cc604309b66f6f45cce02cd734934cd4e (diff)
Bluetooth: Fix kernel crash on L2CAP stress tests
Added very simple check that req buffer has enough space to fit configuration parameters. Shall be enough to reject packets with configuration size more than req buffer. Crash trace below [ 6069.659393] Unable to handle kernel paging request at virtual address 02000205 [ 6069.673034] Internal error: Oops: 805 [#1] PREEMPT ... [ 6069.727172] PC is at l2cap_add_conf_opt+0x70/0xf0 [l2cap] [ 6069.732604] LR is at l2cap_recv_frame+0x1350/0x2e78 [l2cap] ... [ 6070.030303] Backtrace: [ 6070.032806] [<bf1c2880>] (l2cap_add_conf_opt+0x0/0xf0 [l2cap]) from [<bf1c6624>] (l2cap_recv_frame+0x1350/0x2e78 [l2cap]) [ 6070.043823] r8:dc5d3100 r7:df2a91d6 r6:00000001 r5:df2a8000 r4:00000200 [ 6070.050659] [<bf1c52d4>] (l2cap_recv_frame+0x0/0x2e78 [l2cap]) from [<bf1c8408>] (l2cap_recv_acldata+0x2bc/0x350 [l2cap]) [ 6070.061798] [<bf1c814c>] (l2cap_recv_acldata+0x0/0x350 [l2cap]) from [<bf0037a4>] (hci_rx_task+0x244/0x478 [bluetooth]) [ 6070.072631] r6:dc647700 r5:00000001 r4:df2ab740 [ 6070.077362] [<bf003560>] (hci_rx_task+0x0/0x478 [bluetooth]) from [<c006b9fc>] (tasklet_action+0x78/0xd8) [ 6070.087005] [<c006b984>] (tasklet_action+0x0/0xd8) from [<c006c160>] Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com> Acked-by: Gustavo F. Padovan <gustavo@padovan.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/l2cap.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 43e17f7d7ecd..7794a2e2adce 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2832,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
2832 int len = cmd->len - sizeof(*rsp); 2832 int len = cmd->len - sizeof(*rsp);
2833 char req[64]; 2833 char req[64];
2834 2834
2835 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2836 l2cap_send_disconn_req(conn, sk);
2837 goto done;
2838 }
2839
2835 /* throw out any old stored conf requests */ 2840 /* throw out any old stored conf requests */
2836 result = L2CAP_CONF_SUCCESS; 2841 result = L2CAP_CONF_SUCCESS;
2837 len = l2cap_parse_conf_rsp(sk, rsp->data, 2842 len = l2cap_parse_conf_rsp(sk, rsp->data,