}
 
 static inline int l2cap_command_rej(struct l2cap_conn *conn,
-                                   struct l2cap_cmd_hdr *cmd, u8 *data)
+                                   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                   u8 *data)
 {
        struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
 
+       if (cmd_len < sizeof(*rej))
+               return -EPROTO;
+
        if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
                return 0;
 
 }
 
 static int l2cap_connect_req(struct l2cap_conn *conn,
-                            struct l2cap_cmd_hdr *cmd, u8 *data)
+                            struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
        struct hci_dev *hdev = conn->hcon->hdev;
        struct hci_conn *hcon = conn->hcon;
 
+       if (cmd_len < sizeof(struct l2cap_conn_req))
+               return -EPROTO;
+
        hci_dev_lock(hdev);
        if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
            !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
 }
 
 static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
-                                   struct l2cap_cmd_hdr *cmd, u8 *data)
+                                   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                   u8 *data)
 {
        struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
        u16 scid, dcid, result, status;
        u8 req[128];
        int err;
 
+       if (cmd_len < sizeof(*rsp))
+               return -EPROTO;
+
        scid   = __le16_to_cpu(rsp->scid);
        dcid   = __le16_to_cpu(rsp->dcid);
        result = __le16_to_cpu(rsp->result);
        struct l2cap_chan *chan;
        int len, err = 0;
 
+       if (cmd_len < sizeof(*req))
+               return -EPROTO;
+
        dcid  = __le16_to_cpu(req->dcid);
        flags = __le16_to_cpu(req->flags);
 
 
        /* Reject if config buffer is too small. */
        len = cmd_len - sizeof(*req);
-       if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
+       if (chan->conf_len + len > sizeof(chan->conf_req)) {
                l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
                               l2cap_build_conf_rsp(chan, rsp,
                               L2CAP_CONF_REJECT, flags), rsp);
 }
 
 static inline int l2cap_config_rsp(struct l2cap_conn *conn,
-                                  struct l2cap_cmd_hdr *cmd, u8 *data)
+                                  struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                  u8 *data)
 {
        struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
        u16 scid, flags, result;
        struct l2cap_chan *chan;
-       int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
+       int len = cmd_len - sizeof(*rsp);
        int err = 0;
 
+       if (cmd_len < sizeof(*rsp))
+               return -EPROTO;
+
        scid   = __le16_to_cpu(rsp->scid);
        flags  = __le16_to_cpu(rsp->flags);
        result = __le16_to_cpu(rsp->result);
 }
 
 static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
-                                      struct l2cap_cmd_hdr *cmd, u8 *data)
+                                      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                      u8 *data)
 {
        struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
        struct l2cap_disconn_rsp rsp;
        struct l2cap_chan *chan;
        struct sock *sk;
 
+       if (cmd_len != sizeof(*req))
+               return -EPROTO;
+
        scid = __le16_to_cpu(req->scid);
        dcid = __le16_to_cpu(req->dcid);
 
 }
 
 static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
-                                      struct l2cap_cmd_hdr *cmd, u8 *data)
+                                      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                      u8 *data)
 {
        struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
        u16 dcid, scid;
        struct l2cap_chan *chan;
 
+       if (cmd_len != sizeof(*rsp))
+               return -EPROTO;
+
        scid = __le16_to_cpu(rsp->scid);
        dcid = __le16_to_cpu(rsp->dcid);
 
 }
 
 static inline int l2cap_information_req(struct l2cap_conn *conn,
-                                       struct l2cap_cmd_hdr *cmd, u8 *data)
+                                       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                       u8 *data)
 {
        struct l2cap_info_req *req = (struct l2cap_info_req *) data;
        u16 type;
 
+       if (cmd_len != sizeof(*req))
+               return -EPROTO;
+
        type = __le16_to_cpu(req->type);
 
        BT_DBG("type 0x%4.4x", type);
 }
 
 static inline int l2cap_information_rsp(struct l2cap_conn *conn,
-                                       struct l2cap_cmd_hdr *cmd, u8 *data)
+                                       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                       u8 *data)
 {
        struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
        u16 type, result;
 
+       if (cmd_len != sizeof(*rsp))
+               return -EPROTO;
+
        type   = __le16_to_cpu(rsp->type);
        result = __le16_to_cpu(rsp->result);
 
 
        switch (cmd->code) {
        case L2CAP_COMMAND_REJ:
-               l2cap_command_rej(conn, cmd, data);
+               l2cap_command_rej(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CONN_REQ:
-               err = l2cap_connect_req(conn, cmd, data);
+               err = l2cap_connect_req(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CONN_RSP:
        case L2CAP_CREATE_CHAN_RSP:
-               err = l2cap_connect_create_rsp(conn, cmd, data);
+               err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CONF_REQ:
                break;
 
        case L2CAP_CONF_RSP:
-               err = l2cap_config_rsp(conn, cmd, data);
+               err = l2cap_config_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_DISCONN_REQ:
-               err = l2cap_disconnect_req(conn, cmd, data);
+               err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_DISCONN_RSP:
-               err = l2cap_disconnect_rsp(conn, cmd, data);
+               err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_ECHO_REQ:
                break;
 
        case L2CAP_INFO_REQ:
-               err = l2cap_information_req(conn, cmd, data);
+               err = l2cap_information_req(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_INFO_RSP:
-               err = l2cap_information_rsp(conn, cmd, data);
+               err = l2cap_information_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CREATE_CHAN_REQ: