Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
53729eb174
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 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;
|
||||
|
||||
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++;
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -58,7 +58,7 @@ static int l2cap_validate_bredr_psm(u16 psm)
|
|||
return -EINVAL;
|
||||
|
||||
/* Restrict usage of well-known PSMs */
|
||||
if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE))
|
||||
if (psm < L2CAP_PSM_DYN_START && !capable(CAP_NET_BIND_SERVICE))
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
|
@ -67,11 +67,11 @@ static int l2cap_validate_bredr_psm(u16 psm)
|
|||
static int l2cap_validate_le_psm(u16 psm)
|
||||
{
|
||||
/* Valid LE_PSM ranges are defined only until 0x00ff */
|
||||
if (psm > 0x00ff)
|
||||
if (psm > L2CAP_PSM_LE_DYN_END)
|
||||
return -EINVAL;
|
||||
|
||||
/* Restrict fixed, SIG assigned PSM values to CAP_NET_BIND_SERVICE */
|
||||
if (psm <= 0x007f && !capable(CAP_NET_BIND_SERVICE))
|
||||
if (psm < L2CAP_PSM_LE_DYN_START && !capable(CAP_NET_BIND_SERVICE))
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
|
@ -125,6 +125,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
|||
goto done;
|
||||
}
|
||||
|
||||
bacpy(&chan->src, &la.l2_bdaddr);
|
||||
chan->src_type = la.l2_bdaddr_type;
|
||||
|
||||
if (la.l2_cid)
|
||||
err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));
|
||||
else
|
||||
|
@ -156,9 +159,6 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
|||
break;
|
||||
}
|
||||
|
||||
bacpy(&chan->src, &la.l2_bdaddr);
|
||||
chan->src_type = la.l2_bdaddr_type;
|
||||
|
||||
if (chan->psm && bdaddr_type_is_le(chan->src_type))
|
||||
chan->mode = L2CAP_MODE_LE_FLOWCTL;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue