diff options
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 0b54b7dd8401..daa7a988d9a6 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1008,10 +1008,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
1008 | goto done; | 1008 | goto done; |
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 && | 1011 | if (la.l2_psm) { |
1012 | !capable(CAP_NET_BIND_SERVICE)) { | 1012 | __u16 psm = __le16_to_cpu(la.l2_psm); |
1013 | err = -EACCES; | 1013 | |
1014 | goto done; | 1014 | /* PSM must be odd and lsb of upper byte must be 0 */ |
1015 | if ((psm & 0x0101) != 0x0001) { | ||
1016 | err = -EINVAL; | ||
1017 | goto done; | ||
1018 | } | ||
1019 | |||
1020 | /* Restrict usage of well-known PSMs */ | ||
1021 | if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { | ||
1022 | err = -EACCES; | ||
1023 | goto done; | ||
1024 | } | ||
1015 | } | 1025 | } |
1016 | 1026 | ||
1017 | write_lock_bh(&l2cap_sk_list.lock); | 1027 | write_lock_bh(&l2cap_sk_list.lock); |
@@ -1190,6 +1200,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
1190 | goto done; | 1200 | goto done; |
1191 | } | 1201 | } |
1192 | 1202 | ||
1203 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
1204 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && | ||
1205 | sk->sk_type != SOCK_RAW) { | ||
1206 | err = -EINVAL; | ||
1207 | goto done; | ||
1208 | } | ||
1209 | |||
1193 | /* Set destination address and psm */ | 1210 | /* Set destination address and psm */ |
1194 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | 1211 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); |
1195 | l2cap_pi(sk)->psm = la.l2_psm; | 1212 | l2cap_pi(sk)->psm = la.l2_psm; |
@@ -1635,7 +1652,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1635 | 1652 | ||
1636 | *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err); | 1653 | *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err); |
1637 | if (!*frag) | 1654 | if (!*frag) |
1638 | return -EFAULT; | 1655 | return err; |
1639 | if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) | 1656 | if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) |
1640 | return -EFAULT; | 1657 | return -EFAULT; |
1641 | 1658 | ||
@@ -1661,7 +1678,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr | |||
1661 | skb = bt_skb_send_alloc(sk, count + hlen, | 1678 | skb = bt_skb_send_alloc(sk, count + hlen, |
1662 | msg->msg_flags & MSG_DONTWAIT, &err); | 1679 | msg->msg_flags & MSG_DONTWAIT, &err); |
1663 | if (!skb) | 1680 | if (!skb) |
1664 | return ERR_PTR(-ENOMEM); | 1681 | return ERR_PTR(err); |
1665 | 1682 | ||
1666 | /* Create L2CAP header */ | 1683 | /* Create L2CAP header */ |
1667 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1684 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
@@ -1690,7 +1707,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *ms | |||
1690 | skb = bt_skb_send_alloc(sk, count + hlen, | 1707 | skb = bt_skb_send_alloc(sk, count + hlen, |
1691 | msg->msg_flags & MSG_DONTWAIT, &err); | 1708 | msg->msg_flags & MSG_DONTWAIT, &err); |
1692 | if (!skb) | 1709 | if (!skb) |
1693 | return ERR_PTR(-ENOMEM); | 1710 | return ERR_PTR(err); |
1694 | 1711 | ||
1695 | /* Create L2CAP header */ | 1712 | /* Create L2CAP header */ |
1696 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1713 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
@@ -1727,7 +1744,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m | |||
1727 | skb = bt_skb_send_alloc(sk, count + hlen, | 1744 | skb = bt_skb_send_alloc(sk, count + hlen, |
1728 | msg->msg_flags & MSG_DONTWAIT, &err); | 1745 | msg->msg_flags & MSG_DONTWAIT, &err); |
1729 | if (!skb) | 1746 | if (!skb) |
1730 | return ERR_PTR(-ENOMEM); | 1747 | return ERR_PTR(err); |
1731 | 1748 | ||
1732 | /* Create L2CAP header */ | 1749 | /* Create L2CAP header */ |
1733 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1750 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
@@ -1934,6 +1951,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1934 | 1951 | ||
1935 | release_sock(sk); | 1952 | release_sock(sk); |
1936 | 1953 | ||
1954 | if (sock->type == SOCK_STREAM) | ||
1955 | return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); | ||
1956 | |||
1937 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); | 1957 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); |
1938 | } | 1958 | } |
1939 | 1959 | ||
@@ -2891,7 +2911,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2891 | struct l2cap_chan_list *list = &conn->chan_list; | 2911 | struct l2cap_chan_list *list = &conn->chan_list; |
2892 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 2912 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
2893 | struct l2cap_conn_rsp rsp; | 2913 | struct l2cap_conn_rsp rsp; |
2894 | struct sock *parent, *uninitialized_var(sk); | 2914 | struct sock *parent, *sk = NULL; |
2895 | int result, status = L2CAP_CS_NO_INFO; | 2915 | int result, status = L2CAP_CS_NO_INFO; |
2896 | 2916 | ||
2897 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); | 2917 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); |
@@ -3000,7 +3020,7 @@ sendresp: | |||
3000 | L2CAP_INFO_REQ, sizeof(info), &info); | 3020 | L2CAP_INFO_REQ, sizeof(info), &info); |
3001 | } | 3021 | } |
3002 | 3022 | ||
3003 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && | 3023 | if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && |
3004 | result == L2CAP_CR_SUCCESS) { | 3024 | result == L2CAP_CR_SUCCESS) { |
3005 | u8 buf[128]; | 3025 | u8 buf[128]; |
3006 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 3026 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; |
@@ -3151,6 +3171,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3151 | 3171 | ||
3152 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { | 3172 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { |
3153 | u8 buf[64]; | 3173 | u8 buf[64]; |
3174 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
3154 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 3175 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
3155 | l2cap_build_conf_req(sk, buf), buf); | 3176 | l2cap_build_conf_req(sk, buf), buf); |
3156 | l2cap_pi(sk)->num_conf_req++; | 3177 | l2cap_pi(sk)->num_conf_req++; |
@@ -4643,6 +4664,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4643 | 4664 | ||
4644 | if (flags & ACL_START) { | 4665 | if (flags & ACL_START) { |
4645 | struct l2cap_hdr *hdr; | 4666 | struct l2cap_hdr *hdr; |
4667 | struct sock *sk; | ||
4668 | u16 cid; | ||
4646 | int len; | 4669 | int len; |
4647 | 4670 | ||
4648 | if (conn->rx_len) { | 4671 | if (conn->rx_len) { |
@@ -4653,7 +4676,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4653 | l2cap_conn_unreliable(conn, ECOMM); | 4676 | l2cap_conn_unreliable(conn, ECOMM); |
4654 | } | 4677 | } |
4655 | 4678 | ||
4656 | if (skb->len < 2) { | 4679 | /* Start fragment always begin with Basic L2CAP header */ |
4680 | if (skb->len < L2CAP_HDR_SIZE) { | ||
4657 | BT_ERR("Frame is too short (len %d)", skb->len); | 4681 | BT_ERR("Frame is too short (len %d)", skb->len); |
4658 | l2cap_conn_unreliable(conn, ECOMM); | 4682 | l2cap_conn_unreliable(conn, ECOMM); |
4659 | goto drop; | 4683 | goto drop; |
@@ -4661,6 +4685,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4661 | 4685 | ||
4662 | hdr = (struct l2cap_hdr *) skb->data; | 4686 | hdr = (struct l2cap_hdr *) skb->data; |
4663 | len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE; | 4687 | len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE; |
4688 | cid = __le16_to_cpu(hdr->cid); | ||
4664 | 4689 | ||
4665 | if (len == skb->len) { | 4690 | if (len == skb->len) { |
4666 | /* Complete frame received */ | 4691 | /* Complete frame received */ |
@@ -4677,6 +4702,19 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4677 | goto drop; | 4702 | goto drop; |
4678 | } | 4703 | } |
4679 | 4704 | ||
4705 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); | ||
4706 | |||
4707 | if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { | ||
4708 | BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)", | ||
4709 | len, l2cap_pi(sk)->imtu); | ||
4710 | bh_unlock_sock(sk); | ||
4711 | l2cap_conn_unreliable(conn, ECOMM); | ||
4712 | goto drop; | ||
4713 | } | ||
4714 | |||
4715 | if (sk) | ||
4716 | bh_unlock_sock(sk); | ||
4717 | |||
4680 | /* Allocate skb for the complete frame (with header) */ | 4718 | /* Allocate skb for the complete frame (with header) */ |
4681 | conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); | 4719 | conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); |
4682 | if (!conn->rx_skb) | 4720 | if (!conn->rx_skb) |