From c76633bf38205c9ee640096eb387dce31cb8b8c9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 3 Dec 2015 12:45:19 +0200 Subject: Bluetooth: Use continuous scanning when creating LE connections commit 2f99536a5b34d5b0f54723067d68f6cef3f0fdc6 upstream. All LE connections are now triggered through a preceding passive scan and waiting for a connectable advertising report. This means we've got the best possible guarantee that the device is within range and should be able to request the controller to perform continuous scanning. This way we minimize the risk that we miss out on any advertising packets. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_conn.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'net/bluetooth') diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 85b82f7adbd2..24e9410923d0 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -722,8 +722,12 @@ static void hci_req_add_le_create_conn(struct hci_request *req, if (hci_update_random_address(req, false, &own_addr_type)) return; + /* Set window to be the same value as the interval to enable + * continuous scanning. + */ cp.scan_interval = cpu_to_le16(hdev->le_scan_interval); - cp.scan_window = cpu_to_le16(hdev->le_scan_window); + cp.scan_window = cp.scan_interval; + bacpy(&cp.peer_addr, &conn->dst); cp.peer_addr_type = conn->dst_type; cp.own_address_type = own_addr_type; -- cgit v1.2.3 From 701495c14d09658bffe78e0e605f298752edd36c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 26 Jan 2016 14:31:31 -0500 Subject: Bluetooth: Fix incorrect removing of IRKs commit cff10ce7b4f02718ffd25e3914e60559f5ef6ca0 upstream. The commit cad20c278085d893ebd616cd20c0747a8e9d53c7 was supposed to fix handling of devices first using public addresses and then switching to RPAs after pairing. Unfortunately it missed a couple of key places in the code. 1. When evaluating which devices should be removed from the existing white list we also need to consider whether we have an IRK for them or not, i.e. a call to hci_find_irk_by_addr() is needed. 2. In smp_notify_keys() we should not be requiring the knowledge of the RPA, but should simply keep the IRK around if the other conditions require it. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_request.c | 28 ++++++++++++++++++---------- net/bluetooth/smp.c | 16 ---------------- 2 files changed, 18 insertions(+), 26 deletions(-) (limited to 'net/bluetooth') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 981f8a202c27..02778c5bc149 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -175,21 +175,29 @@ static u8 update_white_list(struct hci_request *req) * command to remove it from the controller. */ list_for_each_entry(b, &hdev->le_white_list, list) { - struct hci_cp_le_del_from_white_list cp; + /* If the device is neither in pend_le_conns nor + * pend_le_reports then remove it from the whitelist. + */ + if (!hci_pend_le_action_lookup(&hdev->pend_le_conns, + &b->bdaddr, b->bdaddr_type) && + !hci_pend_le_action_lookup(&hdev->pend_le_reports, + &b->bdaddr, b->bdaddr_type)) { + struct hci_cp_le_del_from_white_list cp; + + cp.bdaddr_type = b->bdaddr_type; + bacpy(&cp.bdaddr, &b->bdaddr); - if (hci_pend_le_action_lookup(&hdev->pend_le_conns, - &b->bdaddr, b->bdaddr_type) || - hci_pend_le_action_lookup(&hdev->pend_le_reports, - &b->bdaddr, b->bdaddr_type)) { - white_list_entries++; + hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST, + sizeof(cp), &cp); continue; } - cp.bdaddr_type = b->bdaddr_type; - bacpy(&cp.bdaddr, &b->bdaddr); + if (hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) { + /* White list can not be used with RPAs */ + return 0x00; + } - hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST, - sizeof(cp), &cp); + white_list_entries++; } /* Since all no longer valid white list entries have been diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index ffed8a1d4f27..4b175df35184 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1072,22 +1072,6 @@ static void smp_notify_keys(struct l2cap_conn *conn) hcon->dst_type = smp->remote_irk->addr_type; queue_work(hdev->workqueue, &conn->id_addr_update_work); } - - /* When receiving an indentity resolving key for - * a remote device that does not use a resolvable - * private address, just remove the key so that - * it is possible to use the controller white - * list for scanning. - * - * Userspace will have been told to not store - * this key at this point. So it is safe to - * just remove it. - */ - if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { - list_del_rcu(&smp->remote_irk->list); - kfree_rcu(smp->remote_irk, rcu); - smp->remote_irk = NULL; - } } if (smp->csrk) { -- cgit v1.2.3 From cf5d2ff495fdf7b7c3936166ca18f7d37d4f6c25 Mon Sep 17 00:00:00 2001 From: Glenn Ruben Bakke Date: Wed, 13 Jan 2016 16:41:42 +0100 Subject: Bluetooth: 6lowpan: Fix kernel NULL pointer dereferences commit 4c58f3282e3de43d34f8955f8eca676294380bf9 upstream. The fixes provided in this patch assigns a valid net_device structure to skb before dispatching it for further processing. Scenario #1: ============ Bluetooth 6lowpan receives an uncompressed IPv6 header, and dispatches it to netif. The following error occurs: Null pointer dereference error #1 crash log: [ 845.854013] BUG: unable to handle kernel NULL pointer dereference at 0000000000000048 [ 845.855785] IP: [] enqueue_to_backlog+0x56/0x240 ... [ 845.909459] Call Trace: [ 845.911678] [] netif_rx_internal+0x44/0xf0 The first modification fixes the NULL pointer dereference error by assigning dev to the local_skb in order to set a valid net_device before processing the skb by netif_rx_ni(). Scenario #2: ============ Bluetooth 6lowpan receives an UDP compressed message which needs further decompression by nhc_udp. The following error occurs: Null pointer dereference error #2 crash log: [ 63.295149] BUG: unable to handle kernel NULL pointer dereference at 0000000000000840 [ 63.295931] IP: [] udp_uncompress+0x320/0x626 [nhc_udp] The second modification fixes the NULL pointer dereference error by assigning dev to the local_skb in the case of a udp compressed packet. The 6lowpan udp_uncompress function expects that the net_device is set in the skb when checking lltype. Signed-off-by: Glenn Ruben Bakke Signed-off-by: Lukasz Duda Acked-by: Jukka Rissanen Signed-off-by: Johan Hedberg Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/6lowpan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/bluetooth') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 9e9cca3689a0..2b6132fa0faf 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -317,6 +317,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, local_skb->protocol = htons(ETH_P_IPV6); local_skb->pkt_type = PACKET_HOST; + local_skb->dev = dev; skb_set_transport_header(local_skb, sizeof(struct ipv6hdr)); @@ -335,6 +336,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (!local_skb) goto drop; + local_skb->dev = dev; + ret = iphc_decompress(local_skb, dev, chan); if (ret < 0) { kfree_skb(local_skb); @@ -343,7 +346,6 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, local_skb->protocol = htons(ETH_P_IPV6); local_skb->pkt_type = PACKET_HOST; - local_skb->dev = dev; if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) { -- cgit v1.2.3 From 8cf0f282de522d9f44dc2e0f6f58361fdef4d722 Mon Sep 17 00:00:00 2001 From: Lukasz Duda Date: Wed, 13 Jan 2016 16:57:48 +0100 Subject: Bluetooth: 6lowpan: Fix handling of uncompressed IPv6 packets commit 87f5fedb3bebbbb566f847dd0c567fcea49a36a6 upstream. This patch fixes incorrect handling of the 6lowpan packets that contain uncompressed IPv6 header. RFC4944 specifies a special dispatch for 6lowpan to carry uncompressed IPv6 header. This dispatch (1 byte long) has to be removed during reception and skb data pointer has to be moved. To correctly point in the beginning of the IPv6 header the dispatch byte has to be pulled off before packet can be processed by netif_rx_in(). Test scenario: IPv6 packets are not correctly interpreted by the network layer when IPv6 header is not compressed (e.g. ICMPv6 Echo Reply is not propagated correctly to the ICMPv6 layer because the extra byte will make the header look corrupted). Similar approach is done for IEEE 802.15.4. Signed-off-by: Lukasz Duda Signed-off-by: Glenn Ruben Bakke Acked-by: Jukka Rissanen Signed-off-by: Johan Hedberg Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/6lowpan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/bluetooth') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 2b6132fa0faf..795ddd8b2f77 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -307,6 +307,9 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, /* check that it's our buffer */ if (lowpan_is_ipv6(*skb_network_header(skb))) { + /* Pull off the 1-byte of 6lowpan header. */ + skb_pull(skb, 1); + /* Copy the packet so that the IPv6 header is * properly aligned. */ -- cgit v1.2.3