[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20190321061208.16163-4-xiyou.wangcong@gmail.com>
Date: Wed, 20 Mar 2019 23:12:08 -0700
From: Cong Wang <xiyou.wangcong@...il.com>
To: netdev@...r.kernel.org
Cc: Cong Wang <xiyou.wangcong@...il.com>,
Marcel Holtmann <marcel@...tmann.org>,
Johan Hedberg <johan.hedberg@...il.com>
Subject: [Patch net v2 3/3] bluetooth: validate HCI_EV_CMD_COMPLETE packet carefully
Similarly, we need to check skb->data boundary for
HCI_EV_CMD_COMPLETE event too.
Cc: Marcel Holtmann <marcel@...tmann.org>
Cc: Johan Hedberg <johan.hedberg@...il.com>
Signed-off-by: Cong Wang <xiyou.wangcong@...il.com>
---
net/bluetooth/hci_event.c | 258 +++++++++++++++++++++++++++++++-------
1 file changed, 215 insertions(+), 43 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 31aef14dd838..63e14c49f617 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -100,9 +100,13 @@ static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_role_discovery *rp = (void *) skb->data;
+ struct hci_rp_role_discovery *rp;
struct hci_conn *conn;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -119,9 +123,13 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_link_policy *rp = (void *) skb->data;
+ struct hci_rp_read_link_policy *rp;
struct hci_conn *conn;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -138,10 +146,14 @@ static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_write_link_policy *rp = (void *) skb->data;
+ struct hci_rp_write_link_policy *rp;
struct hci_conn *conn;
void *sent;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -163,7 +175,11 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
+ struct hci_rp_read_def_link_policy *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -227,9 +243,13 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_stored_link_key(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_stored_link_key *rp = (void *)skb->data;
+ struct hci_rp_read_stored_link_key *rp;
struct hci_cp_read_stored_link_key *sent;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY);
@@ -245,7 +265,11 @@ static void hci_cc_read_stored_link_key(struct hci_dev *hdev,
static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_delete_stored_link_key *rp = (void *)skb->data;
+ struct hci_rp_delete_stored_link_key *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -281,7 +305,11 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_local_name *rp = (void *) skb->data;
+ struct hci_rp_read_local_name *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -381,7 +409,11 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
+ struct hci_rp_read_class_of_dev *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -418,9 +450,13 @@ static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_voice_setting *rp = (void *) skb->data;
+ struct hci_rp_read_voice_setting *rp;
__u16 setting;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -471,7 +507,11 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev,
static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
+ struct hci_rp_read_num_supported_iac *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -547,7 +587,11 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_local_version *rp = (void *) skb->data;
+ struct hci_rp_read_local_version *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -567,7 +611,11 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_local_commands(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_local_commands *rp = (void *) skb->data;
+ struct hci_rp_read_local_commands *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -582,7 +630,11 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
static void hci_cc_read_local_features(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_local_features *rp = (void *) skb->data;
+ struct hci_rp_read_local_features *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -632,7 +684,11 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
+ struct hci_rp_read_local_ext_features *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -649,7 +705,11 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
+ struct hci_rp_read_flow_control_mode *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -661,7 +721,11 @@ static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_buffer_size *rp = (void *) skb->data;
+ struct hci_rp_read_buffer_size *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -687,7 +751,11 @@ static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_bd_addr *rp = (void *) skb->data;
+ struct hci_rp_read_bd_addr *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -704,7 +772,11 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
+ struct hci_rp_read_page_scan_activity *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -739,7 +811,11 @@ static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
+ struct hci_rp_read_page_scan_type *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -769,7 +845,11 @@ static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
static void hci_cc_read_data_block_size(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_data_block_size *rp = (void *) skb->data;
+ struct hci_rp_read_data_block_size *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -824,7 +904,11 @@ static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
+ struct hci_rp_read_local_amp_info *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -846,7 +930,11 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
+ struct hci_rp_read_inq_rsp_tx_power *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -858,10 +946,14 @@ static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_pin_code_reply *rp = (void *) skb->data;
+ struct hci_rp_pin_code_reply *rp;
struct hci_cp_pin_code_reply *cp;
struct hci_conn *conn;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@@ -886,7 +978,11 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
+ struct hci_rp_pin_code_neg_reply *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -902,7 +998,11 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
+ struct hci_rp_le_read_buffer_size *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -920,7 +1020,11 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
static void hci_cc_le_read_local_features(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_local_features *rp = (void *) skb->data;
+ struct hci_rp_le_read_local_features *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -933,7 +1037,11 @@ static void hci_cc_le_read_local_features(struct hci_dev *hdev,
static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
+ struct hci_rp_le_read_adv_tx_power *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -945,7 +1053,11 @@ static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+ struct hci_rp_user_confirm_reply *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -961,7 +1073,11 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+ struct hci_rp_user_confirm_reply *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -976,7 +1092,11 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+ struct hci_rp_user_confirm_reply *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -992,7 +1112,11 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+ struct hci_rp_user_confirm_reply *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -1008,7 +1132,11 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
+ struct hci_rp_read_local_oob_data *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
}
@@ -1016,7 +1144,11 @@ static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
+ struct hci_rp_read_local_oob_ext_data *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
}
@@ -1333,7 +1465,11 @@ static void hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev,
static void hci_cc_le_read_num_adv_sets(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_num_supported_adv_sets *rp = (void *) skb->data;
+ struct hci_rp_le_read_num_supported_adv_sets *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x No of Adv sets %u", hdev->name, rp->status,
rp->num_of_sets);
@@ -1347,7 +1483,11 @@ static void hci_cc_le_read_num_adv_sets(struct hci_dev *hdev,
static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
+ struct hci_rp_le_read_white_list_size *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
@@ -1411,7 +1551,11 @@ static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
+ struct hci_rp_le_read_supported_states *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -1424,7 +1568,11 @@ static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
static void hci_cc_le_read_def_data_len(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_def_data_len *rp = (void *) skb->data;
+ struct hci_rp_le_read_def_data_len *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -1509,7 +1657,11 @@ static void hci_cc_le_clear_resolv_list(struct hci_dev *hdev,
static void hci_cc_le_read_resolv_list_size(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_resolv_list_size *rp = (void *) skb->data;
+ struct hci_rp_le_read_resolv_list_size *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
@@ -1546,7 +1698,11 @@ static void hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev,
static void hci_cc_le_read_max_data_len(struct hci_dev *hdev,
struct sk_buff *skb)
{
- struct hci_rp_le_read_max_data_len *rp = (void *) skb->data;
+ struct hci_rp_le_read_max_data_len *rp;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
@@ -1614,10 +1770,14 @@ static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_set_ext_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_le_set_ext_adv_params *rp = (void *) skb->data;
+ struct hci_rp_le_set_ext_adv_params *rp;
struct hci_cp_le_set_ext_adv_params *cp;
struct adv_info *adv_instance;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -1645,9 +1805,13 @@ static void hci_cc_set_ext_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_rssi *rp = (void *) skb->data;
+ struct hci_rp_read_rssi *rp;
struct hci_conn *conn;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -1665,9 +1829,13 @@ static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_cp_read_tx_power *sent;
- struct hci_rp_read_tx_power *rp = (void *) skb->data;
+ struct hci_rp_read_tx_power *rp;
struct hci_conn *conn;
+ if (unlikely(!pskb_may_pull(skb, sizeof(*rp))))
+ return;
+ rp = (void *)skb->data;
+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
@@ -3108,7 +3276,11 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
hci_req_complete_t *req_complete,
hci_req_complete_skb_t *req_complete_skb)
{
- struct hci_ev_cmd_complete *ev = (void *) skb->data;
+ struct hci_ev_cmd_complete *ev;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*ev) + 1)))
+ return;
+ ev = (void *)skb->data;
*opcode = __le16_to_cpu(ev->opcode);
*status = skb->data[sizeof(*ev)];
--
2.20.1
Powered by blists - more mailing lists