diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3381abdcc28b..908acbad7177 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -2428,6 +2428,8 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb); void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); +void *hci_sent_cmd_data_len(struct hci_dev *hdev, __u16 opcode, + size_t *len); void *hci_recv_event_data(struct hci_dev *hdev, __u8 event); u32 hci_conn_get_phy(struct hci_conn *conn); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bc77db53b195..c97aec3caba0 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3175,7 +3175,8 @@ int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, EXPORT_SYMBOL(__hci_cmd_send); /* Get data from the previously sent command */ -static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode) +static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode, + size_t *len) { struct hci_command_hdr *hdr; @@ -3187,21 +3188,30 @@ static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode) if (hdr->opcode != cpu_to_le16(opcode)) return NULL; + if (len) + *len = skb->len - HCI_COMMAND_HDR_SIZE; + return skb->data + HCI_COMMAND_HDR_SIZE; } +/* Get data from the previously sent command */ +void *hci_sent_cmd_data_len(struct hci_dev *hdev, __u16 opcode, size_t *len) +{ + void *data; + + /* Check if opcode matches last sent command */ + data = hci_cmd_data(hdev->sent_cmd, opcode, len); + if (!data) + /* Check if opcode matches last request */ + data = hci_cmd_data(hdev->req_skb, opcode, len); + + return data; +} + /* Get data from the previously sent command */ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) { - void *data; - - /* Check if opcode matches last sent command */ - data = hci_cmd_data(hdev->sent_cmd, opcode); - if (!data) - /* Check if opcode matches last request */ - data = hci_cmd_data(hdev->req_skb, opcode); - - return data; + return hci_sent_cmd_data_len(hdev, opcode, NULL); } /* Get data from last received event */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 975c63df23c1..bb4249f8e665 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4491,6 +4491,7 @@ static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status) { struct hci_cp_le_create_cis *cp; bool pending = false; + size_t len; int i; bt_dev_dbg(hdev, "status 0x%2.2x", status); @@ -4498,10 +4499,14 @@ static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status) if (!status) return; - cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CIS); + cp = hci_sent_cmd_data_len(hdev, HCI_OP_LE_CREATE_CIS, &len); if (!cp) return; + if (len < sizeof(*cp) || + len < struct_size(cp, cis, cp->num_cis)) + return; + hci_dev_lock(hdev); /* Remove connection if command failed */