Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53729eb1 authored by David S. Miller's avatar David S. Miller
Browse files


Johan Hedberg says:

====================
pull request: bluetooth 2016-01-30

Here's a set of important Bluetooth fixes for the 4.5 kernel:

 - Two fixes to 6LoWPAN code (one fixing a potential crash)
 - Fix LE pairing with devices using both public and random addresses
 - Fix allocation of dynamic LE PSM values
 - Fix missing COMPATIBLE_IOCTL for UART line discipline

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 99b4dd9f cff10ce7
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1261,6 +1261,9 @@ COMPATIBLE_IOCTL(HCIUNBLOCKADDR)
COMPATIBLE_IOCTL(HCIINQUIRY)
COMPATIBLE_IOCTL(HCIUARTSETPROTO)
COMPATIBLE_IOCTL(HCIUARTGETPROTO)
COMPATIBLE_IOCTL(HCIUARTGETDEVICE)
COMPATIBLE_IOCTL(HCIUARTSETFLAGS)
COMPATIBLE_IOCTL(HCIUARTGETFLAGS)
COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
+6 −0
Original line number Diff line number Diff line
@@ -252,6 +252,12 @@ struct l2cap_conn_rsp {
#define L2CAP_PSM_3DSP		0x0021
#define L2CAP_PSM_IPSP		0x0023 /* 6LoWPAN */

#define L2CAP_PSM_DYN_START	0x1001
#define L2CAP_PSM_DYN_END	0xffff
#define L2CAP_PSM_AUTO_END	0x10ff
#define L2CAP_PSM_LE_DYN_START  0x0080
#define L2CAP_PSM_LE_DYN_END	0x00ff

/* channel identifier */
#define L2CAP_CID_SIGNALING	0x0001
#define L2CAP_CID_CONN_LESS	0x0002
+6 −1
Original line number Diff line number Diff line
@@ -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.
		 */
@@ -317,6 +320,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 +339,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 +349,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) {
+18 −10
Original line number Diff line number Diff line
@@ -688,21 +688,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 (hci_pend_le_action_lookup(&hdev->pend_le_conns,
					      &b->bdaddr, b->bdaddr_type) ||
		    hci_pend_le_action_lookup(&hdev->pend_le_reports,
		/* 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)) {
			white_list_entries++;
			continue;
		}
			struct hci_cp_le_del_from_white_list cp;

			cp.bdaddr_type = b->bdaddr_type;
			bacpy(&cp.bdaddr, &b->bdaddr);

			hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
				    sizeof(cp), &cp);
			continue;
		}

		if (hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) {
			/* White list can not be used with RPAs */
			return 0x00;
		}

		white_list_entries++;
	}

	/* Since all no longer valid white list entries have been
+12 −2
Original line number Diff line number Diff line
@@ -197,10 +197,20 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
		chan->sport = psm;
		err = 0;
	} else {
		u16 p;
		u16 p, start, end, incr;

		if (chan->src_type == BDADDR_BREDR) {
			start = L2CAP_PSM_DYN_START;
			end = L2CAP_PSM_AUTO_END;
			incr = 2;
		} else {
			start = L2CAP_PSM_LE_DYN_START;
			end = L2CAP_PSM_LE_DYN_END;
			incr = 1;
		}

		err = -EINVAL;
		for (p = 0x1001; p < 0x1100; p += 2)
		for (p = start; p <= end; p += incr)
			if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
				chan->psm   = cpu_to_le16(p);
				chan->sport = cpu_to_le16(p);
Loading