aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-08-11 15:06:39 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-08-14 02:49:23 -0400
commit8ae9b9845b3252216cf5d2e033e5cca41bae48ef (patch)
treea87137cef1f5f4c6cde5d25cb6b5a1aed86f401a
parent4befb867b9de8adc56c683f4cf6c9e6c035e94e3 (diff)
Bluetooth: Fix double free of SMP data skb
In the case that the SMP recv callback returns error the calling code in l2cap_core.c expects that it still owns the skb and will try to free it. The SMP code should therefore not try to free the skb if it return an error. This patch fixes such behavior in the SMP command handler function. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/smp.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 7a295d7edc44..5103dc739a17 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1387,10 +1387,8 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1387 return 0; 1387 return 0;
1388 } 1388 }
1389 1389
1390 if (skb->len < 1) { 1390 if (skb->len < 1)
1391 kfree_skb(skb);
1392 return -EILSEQ; 1391 return -EILSEQ;
1393 }
1394 1392
1395 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { 1393 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
1396 err = -EOPNOTSUPP; 1394 err = -EOPNOTSUPP;
@@ -1410,8 +1408,9 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1410 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && 1408 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1411 !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { 1409 !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
1412 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); 1410 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1413 kfree_skb(skb); 1411 reason = SMP_CMD_NOTSUPP;
1414 return -EOPNOTSUPP; 1412 err = -EOPNOTSUPP;
1413 goto done;
1415 } 1414 }
1416 1415
1417 switch (code) { 1416 switch (code) {
@@ -1472,8 +1471,8 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1472done: 1471done:
1473 if (reason) 1472 if (reason)
1474 smp_failure(conn, reason); 1473 smp_failure(conn, reason);
1475 1474 if (!err)
1476 kfree_skb(skb); 1475 kfree_skb(skb);
1477 return err; 1476 return err;
1478} 1477}
1479 1478