Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: Make use of skb_pull to parse L2CAP signaling PDUs

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>

authored by

Luiz Augusto von Dentz and committed by
Marcel Holtmann
55cee73e debdedf2

+13 -16
+13 -16
net/bluetooth/l2cap_core.c
··· 5835 5835 struct sk_buff *skb) 5836 5836 { 5837 5837 struct hci_conn *hcon = conn->hcon; 5838 - u8 *data = skb->data; 5839 - int len = skb->len; 5840 - struct l2cap_cmd_hdr cmd; 5838 + struct l2cap_cmd_hdr *cmd; 5841 5839 int err; 5842 5840 5843 5841 l2cap_raw_recv(conn, skb); ··· 5843 5845 if (hcon->type != ACL_LINK) 5844 5846 goto drop; 5845 5847 5846 - while (len >= L2CAP_CMD_HDR_SIZE) { 5847 - u16 cmd_len; 5848 - memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); 5849 - data += L2CAP_CMD_HDR_SIZE; 5850 - len -= L2CAP_CMD_HDR_SIZE; 5848 + while (skb->len >= L2CAP_CMD_HDR_SIZE) { 5849 + u16 len; 5851 5850 5852 - cmd_len = le16_to_cpu(cmd.len); 5851 + cmd = (void *) skb->data; 5852 + skb_pull(skb, L2CAP_CMD_HDR_SIZE); 5853 5853 5854 - BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, 5855 - cmd.ident); 5854 + len = le16_to_cpu(cmd->len); 5856 5855 5857 - if (cmd_len > len || !cmd.ident) { 5856 + BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, 5857 + cmd->ident); 5858 + 5859 + if (len > skb->len || !cmd->ident) { 5858 5860 BT_DBG("corrupted command"); 5859 5861 break; 5860 5862 } 5861 5863 5862 - err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); 5864 + err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data); 5863 5865 if (err) { 5864 5866 struct l2cap_cmd_rej_unk rej; 5865 5867 5866 5868 BT_ERR("Wrong link type (%d)", err); 5867 5869 5868 5870 rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); 5869 - l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, 5871 + l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, 5870 5872 sizeof(rej), &rej); 5871 5873 } 5872 5874 5873 - data += cmd_len; 5874 - len -= cmd_len; 5875 + skb_pull(skb, len); 5875 5876 } 5876 5877 5877 5878 drop: