Bluetooth: Make use of skb_pull to parse L2CAP signaling PDUs
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 6 Mar 2020 22:51:27 +0000 (14:51 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Sun, 8 Mar 2020 07:44:22 +0000 (08:44 +0100)
This uses skb_pull when parsing signalling PDUs so skb->data for
pointing to the current PDU and skb->len as the remaining bytes to be
processed.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap_core.c

index dd20212..4286483 100644 (file)
@@ -5835,9 +5835,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
                                     struct sk_buff *skb)
 {
        struct hci_conn *hcon = conn->hcon;
-       u8 *data = skb->data;
-       int len = skb->len;
-       struct l2cap_cmd_hdr cmd;
+       struct l2cap_cmd_hdr *cmd;
        int err;
 
        l2cap_raw_recv(conn, skb);
@@ -5845,35 +5843,34 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
        if (hcon->type != ACL_LINK)
                goto drop;
 
-       while (len >= L2CAP_CMD_HDR_SIZE) {
-               u16 cmd_len;
-               memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-               data += L2CAP_CMD_HDR_SIZE;
-               len  -= L2CAP_CMD_HDR_SIZE;
+       while (skb->len >= L2CAP_CMD_HDR_SIZE) {
+               u16 len;
+
+               cmd = (void *) skb->data;
+               skb_pull(skb, L2CAP_CMD_HDR_SIZE);
 
-               cmd_len = le16_to_cpu(cmd.len);
+               len = le16_to_cpu(cmd->len);
 
-               BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
-                      cmd.ident);
+               BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len,
+                      cmd->ident);
 
-               if (cmd_len > len || !cmd.ident) {
+               if (len > skb->len || !cmd->ident) {
                        BT_DBG("corrupted command");
                        break;
                }
 
-               err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
+               err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data);
                if (err) {
                        struct l2cap_cmd_rej_unk rej;
 
                        BT_ERR("Wrong link type (%d)", err);
 
                        rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
-                       l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
+                       l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
                                       sizeof(rej), &rej);
                }
 
-               data += cmd_len;
-               len  -= cmd_len;
+               skb_pull(skb, len);
        }
 
 drop: