Skip to content

Commit 91cd99f

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: ipv6: Fix OOPS in ip6_dst_lookup_tail(). ipsec: Restore larval states and socket policies in dump [Bluetooth] Reject L2CAP connections on an insecure ACL link [Bluetooth] Enforce correct authentication requirements [Bluetooth] Fix reference counting during ACL config stage
2 parents 5b0dac7 + e550dfb commit 91cd99f

File tree

9 files changed

+89
-51
lines changed

9 files changed

+89
-51
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,8 @@ int hci_conn_del(struct hci_conn *conn);
325325
void hci_conn_hash_flush(struct hci_dev *hdev);
326326
void hci_conn_check_pending(struct hci_dev *hdev);
327327

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);
329330
int hci_conn_auth(struct hci_conn *conn);
330331
int hci_conn_encrypt(struct hci_conn *conn);
331332
int hci_conn_change_link_key(struct hci_conn *conn);

net/bluetooth/af_bluetooth.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
#define BT_DBG(D...)
5050
#endif
5151

52-
#define VERSION "2.12"
52+
#define VERSION "2.13"
5353

5454
/* Bluetooth sockets */
5555
#define BT_MAX_PROTO 8

net/bluetooth/hci_conn.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ EXPORT_SYMBOL(hci_get_route);
330330

331331
/* Create SCO or ACL connection.
332332
* 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)
334334
{
335335
struct hci_conn *acl;
336336
struct hci_conn *sco;
@@ -344,8 +344,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
344344

345345
hci_conn_hold(acl);
346346

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;
348349
hci_acl_connect(acl);
350+
}
349351

350352
if (type == ACL_LINK)
351353
return acl;
@@ -374,14 +376,27 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
374376
}
375377
EXPORT_SYMBOL(hci_connect);
376378

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+
377392
/* Authenticate remote device */
378393
int hci_conn_auth(struct hci_conn *conn)
379394
{
380395
BT_DBG("conn %p", conn);
381396

382397
if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) {
383398
if (!(conn->auth_type & 0x01)) {
384-
conn->auth_type = HCI_AT_GENERAL_BONDING_MITM;
399+
conn->auth_type |= 0x01;
385400
conn->link_mode &= ~HCI_LM_AUTH;
386401
}
387402
}

net/bluetooth/hci_event.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,14 +1605,11 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
16051605

16061606
if (conn->state == BT_CONFIG) {
16071607
if (!ev->status && hdev->ssp_mode > 0 &&
1608-
conn->ssp_mode > 0) {
1609-
if (conn->out) {
1610-
struct hci_cp_auth_requested cp;
1611-
cp.handle = ev->handle;
1612-
hci_send_cmd(hdev,
1613-
HCI_OP_AUTH_REQUESTED,
1608+
conn->ssp_mode > 0 && conn->out) {
1609+
struct hci_cp_auth_requested cp;
1610+
cp.handle = ev->handle;
1611+
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
16141612
sizeof(cp), &cp);
1615-
}
16161613
} else {
16171614
conn->state = BT_CONNECTED;
16181615
hci_proto_connect_cfm(conn, ev->status);

net/bluetooth/l2cap.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
#define BT_DBG(D...)
5656
#endif
5757

58-
#define VERSION "2.10"
58+
#define VERSION "2.11"
5959

6060
static u32 l2cap_feat_mask = 0x0000;
6161

@@ -778,6 +778,7 @@ static int l2cap_do_connect(struct sock *sk)
778778
struct l2cap_conn *conn;
779779
struct hci_conn *hcon;
780780
struct hci_dev *hdev;
781+
__u8 auth_type;
781782
int err = 0;
782783

783784
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)
789790

790791
err = -ENOMEM;
791792

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);
793808
if (!hcon)
794809
goto done;
795810

@@ -1553,10 +1568,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
15531568
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
15541569
struct l2cap_conn_rsp rsp;
15551570
struct sock *sk, *parent;
1556-
int result, status = 0;
1571+
int result, status = L2CAP_CS_NO_INFO;
15571572

15581573
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
1559-
__le16 psm = req->psm;
1574+
__le16 psm = req->psm;
15601575

15611576
BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
15621577

@@ -1567,6 +1582,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
15671582
goto sendresp;
15681583
}
15691584

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+
15701592
result = L2CAP_CR_NO_MEM;
15711593

15721594
/* Check for backlog size */
@@ -2224,7 +2246,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
22242246
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
22252247
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
22262248
rsp.result = cpu_to_le16(result);
2227-
rsp.status = cpu_to_le16(0);
2249+
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
22282250
l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
22292251
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
22302252
}
@@ -2296,7 +2318,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
22962318
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
22972319
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
22982320
rsp.result = cpu_to_le16(result);
2299-
rsp.status = cpu_to_le16(0);
2321+
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
23002322
l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
23012323
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
23022324
}

net/bluetooth/sco.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static int sco_connect(struct sock *sk)
200200
else
201201
type = SCO_LINK;
202202

203-
hcon = hci_connect(hdev, type, dst);
203+
hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING);
204204
if (!hcon)
205205
goto done;
206206

net/ipv6/ip6_output.c

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -943,39 +943,39 @@ static int ip6_dst_lookup_tail(struct sock *sk,
943943
}
944944

945945
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
946-
/*
947-
* Here if the dst entry we've looked up
948-
* has a neighbour entry that is in the INCOMPLETE
949-
* state and the src address from the flow is
950-
* marked as OPTIMISTIC, we release the found
951-
* dst entry and replace it instead with the
952-
* dst entry of the nexthop router
953-
*/
954-
if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
955-
struct inet6_ifaddr *ifp;
956-
struct flowi fl_gw;
957-
int redirect;
958-
959-
ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
960-
(*dst)->dev, 1);
961-
962-
redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
963-
if (ifp)
964-
in6_ifa_put(ifp);
965-
966-
if (redirect) {
967-
/*
968-
* We need to get the dst entry for the
969-
* default router instead
970-
*/
971-
dst_release(*dst);
972-
memcpy(&fl_gw, fl, sizeof(struct flowi));
973-
memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
974-
*dst = ip6_route_output(net, sk, &fl_gw);
975-
if ((err = (*dst)->error))
976-
goto out_err_release;
977-
}
946+
/*
947+
* Here if the dst entry we've looked up
948+
* has a neighbour entry that is in the INCOMPLETE
949+
* state and the src address from the flow is
950+
* marked as OPTIMISTIC, we release the found
951+
* dst entry and replace it instead with the
952+
* dst entry of the nexthop router
953+
*/
954+
if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
955+
struct inet6_ifaddr *ifp;
956+
struct flowi fl_gw;
957+
int redirect;
958+
959+
ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
960+
(*dst)->dev, 1);
961+
962+
redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
963+
if (ifp)
964+
in6_ifa_put(ifp);
965+
966+
if (redirect) {
967+
/*
968+
* We need to get the dst entry for the
969+
* default router instead
970+
*/
971+
dst_release(*dst);
972+
memcpy(&fl_gw, fl, sizeof(struct flowi));
973+
memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
974+
*dst = ip6_route_output(net, sk, &fl_gw);
975+
if ((err = (*dst)->error))
976+
goto out_err_release;
978977
}
978+
}
979979
#endif
980980

981981
return 0;

net/xfrm/xfrm_policy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
10771077
struct hlist_head *chain = policy_hash_bysel(&pol->selector,
10781078
pol->family, dir);
10791079

1080+
list_add_tail(&pol->bytype, &xfrm_policy_bytype[pol->type]);
10801081
hlist_add_head(&pol->bydst, chain);
10811082
hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
10821083
xfrm_policy_count[dir]++;

net/xfrm/xfrm_state.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
858858

859859
if (km_query(x, tmpl, pol) == 0) {
860860
x->km.state = XFRM_STATE_ACQ;
861+
list_add_tail(&x->all, &xfrm_state_all);
861862
hlist_add_head(&x->bydst, xfrm_state_bydst+h);
862863
h = xfrm_src_hash(daddr, saddr, family);
863864
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
10551056
xfrm_state_hold(x);
10561057
x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
10571058
add_timer(&x->timer);
1059+
list_add_tail(&x->all, &xfrm_state_all);
10581060
hlist_add_head(&x->bydst, xfrm_state_bydst+h);
10591061
h = xfrm_src_hash(daddr, saddr, family);
10601062
hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);

0 commit comments

Comments
 (0)