diff options
| -rw-r--r-- | include/net/bluetooth/hci_core.h | 3 | ||||
| -rw-r--r-- | net/bluetooth/af_bluetooth.c | 2 | ||||
| -rw-r--r-- | net/bluetooth/hci_conn.c | 21 | ||||
| -rw-r--r-- | net/bluetooth/hci_event.c | 11 | ||||
| -rw-r--r-- | net/bluetooth/l2cap.c | 34 | ||||
| -rw-r--r-- | net/bluetooth/sco.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 64 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 1 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 2 |
9 files changed, 89 insertions, 51 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index cbf751094688..46a43b721dd6 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
| @@ -325,7 +325,8 @@ int hci_conn_del(struct hci_conn *conn); | |||
| 325 | void hci_conn_hash_flush(struct hci_dev *hdev); | 325 | void hci_conn_hash_flush(struct hci_dev *hdev); |
| 326 | void hci_conn_check_pending(struct hci_dev *hdev); | 326 | void hci_conn_check_pending(struct hci_dev *hdev); |
| 327 | 327 | ||
| 328 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src); | 328 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); |
| 329 | int hci_conn_check_link_mode(struct hci_conn *conn); | ||
| 329 | int hci_conn_auth(struct hci_conn *conn); | 330 | int hci_conn_auth(struct hci_conn *conn); |
| 330 | int hci_conn_encrypt(struct hci_conn *conn); | 331 | int hci_conn_encrypt(struct hci_conn *conn); |
| 331 | int hci_conn_change_link_key(struct hci_conn *conn); | 332 | int hci_conn_change_link_key(struct hci_conn *conn); |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 1edfdf4c095b..f6348e078aa4 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
| @@ -49,7 +49,7 @@ | |||
| 49 | #define BT_DBG(D...) | 49 | #define BT_DBG(D...) |
| 50 | #endif | 50 | #endif |
| 51 | 51 | ||
| 52 | #define VERSION "2.12" | 52 | #define VERSION "2.13" |
| 53 | 53 | ||
| 54 | /* Bluetooth sockets */ | 54 | /* Bluetooth sockets */ |
| 55 | #define BT_MAX_PROTO 8 | 55 | #define BT_MAX_PROTO 8 |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index ca8d05245ca0..b7002429f152 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -330,7 +330,7 @@ EXPORT_SYMBOL(hci_get_route); | |||
| 330 | 330 | ||
| 331 | /* Create SCO or ACL connection. | 331 | /* Create SCO or ACL connection. |
| 332 | * Device _must_ be locked */ | 332 | * Device _must_ be locked */ |
| 333 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) | 333 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type) |
| 334 | { | 334 | { |
| 335 | struct hci_conn *acl; | 335 | struct hci_conn *acl; |
| 336 | struct hci_conn *sco; | 336 | struct hci_conn *sco; |
| @@ -344,8 +344,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
| 344 | 344 | ||
| 345 | hci_conn_hold(acl); | 345 | hci_conn_hold(acl); |
| 346 | 346 | ||
| 347 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) | 347 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { |
| 348 | acl->auth_type = auth_type; | ||
| 348 | hci_acl_connect(acl); | 349 | hci_acl_connect(acl); |
| 350 | } | ||
| 349 | 351 | ||
| 350 | if (type == ACL_LINK) | 352 | if (type == ACL_LINK) |
| 351 | return acl; | 353 | return acl; |
| @@ -374,6 +376,19 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
| 374 | } | 376 | } |
| 375 | EXPORT_SYMBOL(hci_connect); | 377 | EXPORT_SYMBOL(hci_connect); |
| 376 | 378 | ||
| 379 | /* Check link security requirement */ | ||
| 380 | int hci_conn_check_link_mode(struct hci_conn *conn) | ||
| 381 | { | ||
| 382 | BT_DBG("conn %p", conn); | ||
| 383 | |||
| 384 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 && | ||
| 385 | !(conn->link_mode & HCI_LM_ENCRYPT)) | ||
| 386 | return 0; | ||
| 387 | |||
| 388 | return 1; | ||
| 389 | } | ||
| 390 | EXPORT_SYMBOL(hci_conn_check_link_mode); | ||
| 391 | |||
| 377 | /* Authenticate remote device */ | 392 | /* Authenticate remote device */ |
| 378 | int hci_conn_auth(struct hci_conn *conn) | 393 | int hci_conn_auth(struct hci_conn *conn) |
| 379 | { | 394 | { |
| @@ -381,7 +396,7 @@ int hci_conn_auth(struct hci_conn *conn) | |||
| 381 | 396 | ||
| 382 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { | 397 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { |
| 383 | if (!(conn->auth_type & 0x01)) { | 398 | if (!(conn->auth_type & 0x01)) { |
| 384 | conn->auth_type = HCI_AT_GENERAL_BONDING_MITM; | 399 | conn->auth_type |= 0x01; |
| 385 | conn->link_mode &= ~HCI_LM_AUTH; | 400 | conn->link_mode &= ~HCI_LM_AUTH; |
| 386 | } | 401 | } |
| 387 | } | 402 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0e3db289f4be..ad7a553d7713 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -1605,14 +1605,11 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b | |||
| 1605 | 1605 | ||
| 1606 | if (conn->state == BT_CONFIG) { | 1606 | if (conn->state == BT_CONFIG) { |
| 1607 | if (!ev->status && hdev->ssp_mode > 0 && | 1607 | if (!ev->status && hdev->ssp_mode > 0 && |
| 1608 | conn->ssp_mode > 0) { | 1608 | conn->ssp_mode > 0 && conn->out) { |
| 1609 | if (conn->out) { | 1609 | struct hci_cp_auth_requested cp; |
| 1610 | struct hci_cp_auth_requested cp; | 1610 | cp.handle = ev->handle; |
| 1611 | cp.handle = ev->handle; | 1611 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, |
| 1612 | hci_send_cmd(hdev, | ||
| 1613 | HCI_OP_AUTH_REQUESTED, | ||
| 1614 | sizeof(cp), &cp); | 1612 | sizeof(cp), &cp); |
| 1615 | } | ||
| 1616 | } else { | 1613 | } else { |
| 1617 | conn->state = BT_CONNECTED; | 1614 | conn->state = BT_CONNECTED; |
| 1618 | hci_proto_connect_cfm(conn, ev->status); | 1615 | hci_proto_connect_cfm(conn, ev->status); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 3396d5bdef1c..9610a9c85b98 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -55,7 +55,7 @@ | |||
| 55 | #define BT_DBG(D...) | 55 | #define BT_DBG(D...) |
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | #define VERSION "2.10" | 58 | #define VERSION "2.11" |
| 59 | 59 | ||
| 60 | static u32 l2cap_feat_mask = 0x0000; | 60 | static u32 l2cap_feat_mask = 0x0000; |
| 61 | 61 | ||
| @@ -778,6 +778,7 @@ static int l2cap_do_connect(struct sock *sk) | |||
| 778 | struct l2cap_conn *conn; | 778 | struct l2cap_conn *conn; |
| 779 | struct hci_conn *hcon; | 779 | struct hci_conn *hcon; |
| 780 | struct hci_dev *hdev; | 780 | struct hci_dev *hdev; |
| 781 | __u8 auth_type; | ||
| 781 | int err = 0; | 782 | int err = 0; |
| 782 | 783 | ||
| 783 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); | 784 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); |
| @@ -789,7 +790,21 @@ static int l2cap_do_connect(struct sock *sk) | |||
| 789 | 790 | ||
| 790 | err = -ENOMEM; | 791 | err = -ENOMEM; |
| 791 | 792 | ||
| 792 | hcon = hci_connect(hdev, ACL_LINK, dst); | 793 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH || |
| 794 | l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT || | ||
| 795 | l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) { | ||
| 796 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | ||
| 797 | auth_type = HCI_AT_NO_BONDING_MITM; | ||
| 798 | else | ||
| 799 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
| 800 | } else { | ||
| 801 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | ||
| 802 | auth_type = HCI_AT_NO_BONDING; | ||
| 803 | else | ||
| 804 | auth_type = HCI_AT_GENERAL_BONDING; | ||
| 805 | } | ||
| 806 | |||
| 807 | hcon = hci_connect(hdev, ACL_LINK, dst, auth_type); | ||
| 793 | if (!hcon) | 808 | if (!hcon) |
| 794 | goto done; | 809 | goto done; |
| 795 | 810 | ||
| @@ -1553,10 +1568,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
| 1553 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 1568 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
| 1554 | struct l2cap_conn_rsp rsp; | 1569 | struct l2cap_conn_rsp rsp; |
| 1555 | struct sock *sk, *parent; | 1570 | struct sock *sk, *parent; |
| 1556 | int result, status = 0; | 1571 | int result, status = L2CAP_CS_NO_INFO; |
| 1557 | 1572 | ||
| 1558 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); | 1573 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); |
| 1559 | __le16 psm = req->psm; | 1574 | __le16 psm = req->psm; |
| 1560 | 1575 | ||
| 1561 | BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); | 1576 | BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); |
| 1562 | 1577 | ||
| @@ -1567,6 +1582,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
| 1567 | goto sendresp; | 1582 | goto sendresp; |
| 1568 | } | 1583 | } |
| 1569 | 1584 | ||
| 1585 | /* Check if the ACL is secure enough (if not SDP) */ | ||
| 1586 | if (psm != cpu_to_le16(0x0001) && | ||
| 1587 | !hci_conn_check_link_mode(conn->hcon)) { | ||
| 1588 | result = L2CAP_CR_SEC_BLOCK; | ||
| 1589 | goto response; | ||
| 1590 | } | ||
| 1591 | |||
| 1570 | result = L2CAP_CR_NO_MEM; | 1592 | result = L2CAP_CR_NO_MEM; |
| 1571 | 1593 | ||
| 1572 | /* Check for backlog size */ | 1594 | /* Check for backlog size */ |
| @@ -2224,7 +2246,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | |||
| 2224 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 2246 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
| 2225 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2247 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
| 2226 | rsp.result = cpu_to_le16(result); | 2248 | rsp.result = cpu_to_le16(result); |
| 2227 | rsp.status = cpu_to_le16(0); | 2249 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
| 2228 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 2250 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
| 2229 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 2251 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
| 2230 | } | 2252 | } |
| @@ -2296,7 +2318,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
| 2296 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 2318 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
| 2297 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2319 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
| 2298 | rsp.result = cpu_to_le16(result); | 2320 | rsp.result = cpu_to_le16(result); |
| 2299 | rsp.status = cpu_to_le16(0); | 2321 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
| 2300 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 2322 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
| 2301 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 2323 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
| 2302 | } | 2324 | } |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index a16011fedc1d..0cc91e6da76d 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -200,7 +200,7 @@ static int sco_connect(struct sock *sk) | |||
| 200 | else | 200 | else |
| 201 | type = SCO_LINK; | 201 | type = SCO_LINK; |
| 202 | 202 | ||
| 203 | hcon = hci_connect(hdev, type, dst); | 203 | hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING); |
| 204 | if (!hcon) | 204 | if (!hcon) |
| 205 | goto done; | 205 | goto done; |
| 206 | 206 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0e844c2736a7..3df2c442d90b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -943,39 +943,39 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
| 943 | } | 943 | } |
| 944 | 944 | ||
| 945 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 945 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
| 946 | /* | 946 | /* |
| 947 | * Here if the dst entry we've looked up | 947 | * Here if the dst entry we've looked up |
| 948 | * has a neighbour entry that is in the INCOMPLETE | 948 | * has a neighbour entry that is in the INCOMPLETE |
| 949 | * state and the src address from the flow is | 949 | * state and the src address from the flow is |
| 950 | * marked as OPTIMISTIC, we release the found | 950 | * marked as OPTIMISTIC, we release the found |
| 951 | * dst entry and replace it instead with the | 951 | * dst entry and replace it instead with the |
| 952 | * dst entry of the nexthop router | 952 | * dst entry of the nexthop router |
| 953 | */ | 953 | */ |
| 954 | if (!((*dst)->neighbour->nud_state & NUD_VALID)) { | 954 | if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { |
| 955 | struct inet6_ifaddr *ifp; | 955 | struct inet6_ifaddr *ifp; |
| 956 | struct flowi fl_gw; | 956 | struct flowi fl_gw; |
| 957 | int redirect; | 957 | int redirect; |
| 958 | 958 | ||
| 959 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, | 959 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, |
| 960 | (*dst)->dev, 1); | 960 | (*dst)->dev, 1); |
| 961 | 961 | ||
| 962 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); | 962 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); |
| 963 | if (ifp) | 963 | if (ifp) |
| 964 | in6_ifa_put(ifp); | 964 | in6_ifa_put(ifp); |
| 965 | 965 | ||
| 966 | if (redirect) { | 966 | if (redirect) { |
| 967 | /* | 967 | /* |
| 968 | * We need to get the dst entry for the | 968 | * We need to get the dst entry for the |
| 969 | * default router instead | 969 | * default router instead |
| 970 | */ | 970 | */ |
| 971 | dst_release(*dst); | 971 | dst_release(*dst); |
| 972 | memcpy(&fl_gw, fl, sizeof(struct flowi)); | 972 | memcpy(&fl_gw, fl, sizeof(struct flowi)); |
| 973 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); | 973 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); |
| 974 | *dst = ip6_route_output(net, sk, &fl_gw); | 974 | *dst = ip6_route_output(net, sk, &fl_gw); |
| 975 | if ((err = (*dst)->error)) | 975 | if ((err = (*dst)->error)) |
| 976 | goto out_err_release; | 976 | goto out_err_release; |
| 977 | } | ||
| 978 | } | 977 | } |
| 978 | } | ||
| 979 | #endif | 979 | #endif |
| 980 | 980 | ||
| 981 | return 0; | 981 | return 0; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 46914b79d850..b7754b1b73a4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1077,6 +1077,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) | |||
| 1077 | struct hlist_head *chain = policy_hash_bysel(&pol->selector, | 1077 | struct hlist_head *chain = policy_hash_bysel(&pol->selector, |
| 1078 | pol->family, dir); | 1078 | pol->family, dir); |
| 1079 | 1079 | ||
| 1080 | list_add_tail(&pol->bytype, &xfrm_policy_bytype[pol->type]); | ||
| 1080 | hlist_add_head(&pol->bydst, chain); | 1081 | hlist_add_head(&pol->bydst, chain); |
| 1081 | hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index)); | 1082 | hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index)); |
| 1082 | xfrm_policy_count[dir]++; | 1083 | xfrm_policy_count[dir]++; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 7bd62f61593f..0a8f09c3144c 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -858,6 +858,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
| 858 | 858 | ||
| 859 | if (km_query(x, tmpl, pol) == 0) { | 859 | if (km_query(x, tmpl, pol) == 0) { |
| 860 | x->km.state = XFRM_STATE_ACQ; | 860 | x->km.state = XFRM_STATE_ACQ; |
| 861 | list_add_tail(&x->all, &xfrm_state_all); | ||
| 861 | hlist_add_head(&x->bydst, xfrm_state_bydst+h); | 862 | hlist_add_head(&x->bydst, xfrm_state_bydst+h); |
| 862 | h = xfrm_src_hash(daddr, saddr, family); | 863 | h = xfrm_src_hash(daddr, saddr, family); |
| 863 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 864 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); |
| @@ -1055,6 +1056,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
| 1055 | xfrm_state_hold(x); | 1056 | xfrm_state_hold(x); |
| 1056 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; | 1057 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; |
| 1057 | add_timer(&x->timer); | 1058 | add_timer(&x->timer); |
| 1059 | list_add_tail(&x->all, &xfrm_state_all); | ||
| 1058 | hlist_add_head(&x->bydst, xfrm_state_bydst+h); | 1060 | hlist_add_head(&x->bydst, xfrm_state_bydst+h); |
| 1059 | h = xfrm_src_hash(daddr, saddr, family); | 1061 | h = xfrm_src_hash(daddr, saddr, family); |
| 1060 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 1062 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); |
