Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[cascardo/linux.git] / net / bluetooth / l2cap_core.c
index b6f9777..a2b6dfa 100644 (file)
@@ -46,7 +46,6 @@
 bool disable_ertm;
 
 static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
-static u8 l2cap_fixed_chan[8] = { L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS, };
 
 static LIST_HEAD(chan_list);
 static DEFINE_RWLOCK(chan_list_lock);
@@ -424,6 +423,9 @@ struct l2cap_chan *l2cap_chan_create(void)
 
        mutex_init(&chan->lock);
 
+       /* Set default lock nesting level */
+       atomic_set(&chan->nesting, L2CAP_NESTING_NORMAL);
+
        write_lock(&chan_list_lock);
        list_add(&chan->global_l, &chan_list);
        write_unlock(&chan_list_lock);
@@ -567,7 +569,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 
        __clear_chan_timer(chan);
 
-       BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
+       BT_DBG("chan %p, conn %p, err %d, state %s", chan, conn, err,
+              state_to_string(chan->state));
 
        chan->ops->teardown(chan, err);
 
@@ -836,7 +839,10 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
        if (!skb)
                return;
 
-       if (lmp_no_flush_capable(conn->hcon->hdev))
+       /* Use NO_FLUSH if supported or we have an LE link (which does
+        * not support auto-flushing packets) */
+       if (lmp_no_flush_capable(conn->hcon->hdev) ||
+           conn->hcon->type == LE_LINK)
                flags = ACL_START_NO_FLUSH;
        else
                flags = ACL_START;
@@ -870,8 +876,13 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
                return;
        }
 
-       if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
-           lmp_no_flush_capable(hcon->hdev))
+       /* Use NO_FLUSH for LE links (where this is the only option) or
+        * if the BR/EDR link supports it and flushing has not been
+        * explicitly requested (through FLAG_FLUSHABLE).
+        */
+       if (hcon->type == LE_LINK ||
+           (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
+            lmp_no_flush_capable(hcon->hdev)))
                flags = ACL_START_NO_FLUSH;
        else
                flags = ACL_START;
@@ -1108,10 +1119,10 @@ static bool __amp_capable(struct l2cap_chan *chan)
        struct hci_dev *hdev;
        bool amp_available = false;
 
-       if (!conn->hs_enabled)
+       if (!(conn->local_fixed_chan & L2CAP_FC_A2MP))
                return false;
 
-       if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
+       if (!(conn->remote_fixed_chan & L2CAP_FC_A2MP))
                return false;
 
        read_lock(&hci_dev_list_lock);
@@ -2092,8 +2103,7 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
        struct sk_buff **frag;
        int sent = 0;
 
-       if (chan->ops->memcpy_fromiovec(chan, skb_put(skb, count),
-                                       msg->msg_iov, count))
+       if (copy_from_iter(skb_put(skb, count), count, &msg->msg_iter) != count)
                return -EFAULT;
 
        sent += count;
@@ -2113,8 +2123,8 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
 
                *frag = tmp;
 
-               if (chan->ops->memcpy_fromiovec(chan, skb_put(*frag, count),
-                                               msg->msg_iov, count))
+               if (copy_from_iter(skb_put(*frag, count), count,
+                                  &msg->msg_iter) != count)
                        return -EFAULT;
 
                sent += count;
@@ -3084,12 +3094,14 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
 
 static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
 {
-       return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
+       return ((conn->local_fixed_chan & L2CAP_FC_A2MP) &&
+               (conn->feat_mask & L2CAP_FEAT_EXT_WINDOW));
 }
 
 static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
 {
-       return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
+       return ((conn->local_fixed_chan & L2CAP_FC_A2MP) &&
+               (conn->feat_mask & L2CAP_FEAT_EXT_FLOW));
 }
 
 static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
@@ -3318,7 +3330,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
                        break;
 
                case L2CAP_CONF_EWS:
-                       if (!chan->conn->hs_enabled)
+                       if (!(chan->conn->local_fixed_chan & L2CAP_FC_A2MP))
                                return -ECONNREFUSED;
 
                        set_bit(FLAG_EXT_CTRL, &chan->flags);
@@ -3873,9 +3885,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
        hci_dev_lock(hdev);
        if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
            !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
-               mgmt_device_connected(hdev, &hcon->dst, hcon->type,
-                                     hcon->dst_type, 0, NULL, 0,
-                                     hcon->dev_class);
+               mgmt_device_connected(hdev, hcon, 0, NULL, 0);
        hci_dev_unlock(hdev);
 
        l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
@@ -4084,7 +4094,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
                chan->num_conf_req++;
        }
 
-       /* Got Conf Rsp PENDING from remote side and asume we sent
+       /* Got Conf Rsp PENDING from remote side and assume we sent
           Conf Rsp PENDING in the code above */
        if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
            test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
@@ -4324,7 +4334,7 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,
                if (!disable_ertm)
                        feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
                                | L2CAP_FEAT_FCS;
-               if (conn->hs_enabled)
+               if (conn->local_fixed_chan & L2CAP_FC_A2MP)
                        feat_mask |= L2CAP_FEAT_EXT_FLOW
                                | L2CAP_FEAT_EXT_WINDOW;
 
@@ -4335,14 +4345,10 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,
                u8 buf[12];
                struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
 
-               if (conn->hs_enabled)
-                       l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
-               else
-                       l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
-
                rsp->type   = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
                rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
-               memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
+               rsp->data[0] = conn->local_fixed_chan;
+               memset(rsp->data + 1, 0, 7);
                l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
                               buf);
        } else {
@@ -4408,7 +4414,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn,
                break;
 
        case L2CAP_IT_FIXED_CHAN:
-               conn->fixed_chan_mask = rsp->data[0];
+               conn->remote_fixed_chan = rsp->data[0];
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
                conn->info_ident = 0;
 
@@ -4432,7 +4438,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
        if (cmd_len != sizeof(*req))
                return -EPROTO;
 
-       if (!conn->hs_enabled)
+       if (!(conn->local_fixed_chan & L2CAP_FC_A2MP))
                return -EINVAL;
 
        psm = le16_to_cpu(req->psm);
@@ -4862,7 +4868,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
 
        BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
 
-       if (!conn->hs_enabled)
+       if (!(conn->local_fixed_chan & L2CAP_FC_A2MP))
                return -EINVAL;
 
        chan = l2cap_get_chan_by_dcid(conn, icid);
@@ -5217,9 +5223,10 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
                                u8 *data)
 {
        struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
+       struct hci_conn *hcon = conn->hcon;
        u16 dcid, mtu, mps, credits, result;
        struct l2cap_chan *chan;
-       int err;
+       int err, sec_level;
 
        if (cmd_len < sizeof(*rsp))
                return -EPROTO;
@@ -5258,6 +5265,26 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
                l2cap_chan_ready(chan);
                break;
 
+       case L2CAP_CR_AUTHENTICATION:
+       case L2CAP_CR_ENCRYPTION:
+               /* If we already have MITM protection we can't do
+                * anything.
+                */
+               if (hcon->sec_level > BT_SECURITY_MEDIUM) {
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       break;
+               }
+
+               sec_level = hcon->sec_level + 1;
+               if (chan->sec_level < sec_level)
+                       chan->sec_level = sec_level;
+
+               /* We'll need to send a new Connect Request */
+               clear_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags);
+
+               smp_conn_security(hcon, chan->sec_level);
+               break;
+
        default:
                l2cap_chan_del(chan, ECONNREFUSED);
                break;
@@ -5390,7 +5417,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
        mutex_lock(&conn->chan_lock);
        l2cap_chan_lock(pchan);
 
-       if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
+       if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
+                                    SMP_ALLOW_STK)) {
                result = L2CAP_CR_AUTHENTICATION;
                chan = NULL;
                goto response_unlock;
@@ -5494,6 +5522,7 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
        if (credits > max_credits) {
                BT_ERR("LE credits overflow");
                l2cap_send_disconn_req(chan, ECONNRESET);
+               l2cap_chan_unlock(chan);
 
                /* Return 0 so that we don't trigger an unnecessary
                 * command reject packet.
@@ -6931,9 +6960,15 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
 
        conn->feat_mask = 0;
 
-       if (hcon->type == ACL_LINK)
-               conn->hs_enabled = test_bit(HCI_HS_ENABLED,
-                                           &hcon->hdev->dev_flags);
+       conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS;
+
+       if (hcon->type == ACL_LINK &&
+           test_bit(HCI_HS_ENABLED, &hcon->hdev->dev_flags))
+               conn->local_fixed_chan |= L2CAP_FC_A2MP;
+
+       if (bredr_sc_enabled(hcon->hdev) &&
+           test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
+               conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR;
 
        mutex_init(&conn->ident_lock);
        mutex_init(&conn->chan_lock);
@@ -7330,7 +7365,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                l2cap_start_connection(chan);
                        else
                                __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
-               } else if (chan->state == BT_CONNECT2) {
+               } else if (chan->state == BT_CONNECT2 &&
+                          chan->mode != L2CAP_MODE_LE_FLOWCTL) {
                        struct l2cap_conn_rsp rsp;
                        __u16 res, stat;