]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Bluetooth: hci_core: Fix not checking skb length on hci_acldata_packet
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 8 Oct 2024 14:16:48 +0000 (10:16 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2024 18:54:44 +0000 (19:54 +0100)
[ Upstream commit 3fe288a8214e7dd784d1f9b7c9e448244d316b47 ]

This fixes not checking if skb really contains an ACL header otherwise
the code may attempt to access some uninitilized/invalid memory past the
valid skb->data.

Reported-by: syzbot+6ea290ba76d8c1eb1ac2@syzkaller.appspotmail.com
Tested-by: syzbot+6ea290ba76d8c1eb1ac2@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6ea290ba76d8c1eb1ac2
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/bluetooth/hci_core.c

index 789f7f4a09089bfde172a1d4f21c89b911a5662c..3cd7c212375fc7c602c894f902049e9a37d5d17a 100644 (file)
@@ -3829,18 +3829,22 @@ static void hci_tx_work(struct work_struct *work)
 /* ACL data packet */
 static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_acl_hdr *hdr = (void *) skb->data;
+       struct hci_acl_hdr *hdr;
        struct hci_conn *conn;
        __u16 handle, flags;
 
-       skb_pull(skb, HCI_ACL_HDR_SIZE);
+       hdr = skb_pull_data(skb, sizeof(*hdr));
+       if (!hdr) {
+               bt_dev_err(hdev, "ACL packet too small");
+               goto drop;
+       }
 
        handle = __le16_to_cpu(hdr->handle);
        flags  = hci_flags(handle);
        handle = hci_handle(handle);
 
-       BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
-              handle, flags);
+       bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
+                  handle, flags);
 
        hdev->stat.acl_rx++;
 
@@ -3859,6 +3863,7 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
                           handle);
        }
 
+drop:
        kfree_skb(skb);
 }