From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.0 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2266C43381 for ; Thu, 21 Mar 2019 06:12:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 59F24218B0 for ; Thu, 21 Mar 2019 06:12:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="R4HFsf/d" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727687AbfCUGM2 (ORCPT ); Thu, 21 Mar 2019 02:12:28 -0400 Received: from mail-pg1-f169.google.com ([209.85.215.169]:41887 "EHLO mail-pg1-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727507AbfCUGM1 (ORCPT ); Thu, 21 Mar 2019 02:12:27 -0400 Received: by mail-pg1-f169.google.com with SMTP id k11so3506486pgb.8 for ; Wed, 20 Mar 2019 23:12:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0rg7iq84+IIKT4fHoaFWKlIM3jFIKnucKQExGMtWLU8=; b=R4HFsf/dDmk9+ptBbI5PP25rfF9pPe9tnyNsscpw/vHxUKxBOtdbJqEONXUaxB9vwq VRsc9/QBY+j0J4ElKXbt3dJZVU+0sEH+uix4rqmgOQpXeQ/OD+zfMZlvaXoOxX5Nm0YE aMj0xLdwaephYBvHpnVjlyiEUgNdtIHOiYe45hJMrOkLd9rBUxKh1rScszLSRRApuCqV uvtYSL2RK5n2PxR1kVnYLgKx7RsRKPGrpmnQF3rzBEfH4StJw84EQJrQI1KPHTgAbCpI 4GU6WW/ArA3wNUoHkQ+JJ8UHo8DHtdAYITiFu4Zv6d0fKrLNSKGSyzGgkUT26VH+5TpX 1duw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0rg7iq84+IIKT4fHoaFWKlIM3jFIKnucKQExGMtWLU8=; b=LEnp/0k6gPGtfxT8BVtkI5UEW6FZQ2cvm1x4UF6FT/MaO9lHk+nTNN6w/4dRS34v8G dh/wUvXLIWmYIczty2pspxTc79/z2WRlGZ2VF3O7fQsrX+8gDWDaXaC0mWUFGm7NVapk MPtqDLBm5E7EtnqXPvB/YoWQBXDB87vU9E2p5FH9SBX4H6tCJuxxlXUTuhnSspKUpLoE p7XI8Um0gKbhNPkBBHvg/4OS1nuHIdpp3OKjKPtv9e5AHUrXoO3ZiKQkTM4cStNCmyle rYQUpkZexRuM7s667Uh0s8HEwmVRyguyjRjkQQsN7voZiPH4J+mNlGWcOjITAOPQGSez lOug== X-Gm-Message-State: APjAAAXxKUuU9rqSfsIXwnq+S3q4vBNSq8Ry/7aeta0DNwAXQtqNTokB cdMjM+JOxurWaLXSRwQDti3acOWG X-Google-Smtp-Source: APXvYqwCD1+yxUWS2lWjAuiqVV5rCqdgdo6TAR8FPQkPYX0ItzKDDxldGHlMWKlC1rfZGBbio6/cKw== X-Received: by 2002:a62:cd8c:: with SMTP id o134mr1745876pfg.84.1553148746109; Wed, 20 Mar 2019 23:12:26 -0700 (PDT) Received: from tw-172-25-17-123.office.twttr.net ([8.25.197.27]) by smtp.gmail.com with ESMTPSA id v4sm6594426pff.181.2019.03.20.23.12.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 20 Mar 2019 23:12:25 -0700 (PDT) From: Cong Wang To: netdev@vger.kernel.org Cc: Cong Wang , Marcel Holtmann , Johan Hedberg Subject: [Patch net v2 3/3] bluetooth: validate HCI_EV_CMD_COMPLETE packet carefully Date: Wed, 20 Mar 2019 23:12:08 -0700 Message-Id: <20190321061208.16163-4-xiyou.wangcong@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321061208.16163-1-xiyou.wangcong@gmail.com> References: <20190321061208.16163-1-xiyou.wangcong@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Similarly, we need to check skb->data boundary for HCI_EV_CMD_COMPLETE event too. Cc: Marcel Holtmann Cc: Johan Hedberg Signed-off-by: Cong Wang --- 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