An old problem, which is being told or reported many times, shall be raised here again. The point here is that this old bug can do harm and should be fixed. I was told that "the whole hci_event.c file is buggy and has been known for years". This is because of the *Forced Type Conversion* in all events handler functions. That is, these functions directly turn the skb->data to another struct without any sanity checks. Hence, when there are some operations that access the converted structs, OOB access occurs. This phenomenon has been discussed several times. Even the syzbot found several misbehaviors. - out of bounds read in hci_le_direct_adv_report_evt (https://groups.google.com/g/syzkaller-lts-bugs/c/fqfVDl0SRnQ/m/b19iKC4LAwAJ) - out of bounds read in hci_le_ext_adv_report_evt (https://groups.google.com/g/syzkaller/c/VRLy9k6ATAo/m/Kxqjvn4JBAAJ) and old war here: https://linuxlists.cc/l/15/linux-bluetooth/t/3072736 However, these bugs are still not properly fixed because the developers are not aware of the harmfulness. In this mail, I will talk about the potential info leak exploits based on this OOB vulnerability in function hci_cc_read_local_name(). =*=*=*=*=*=*=*=*= BUG DETAILS =*=*=*=*=*=*=*=*= 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; // {1} BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); if (rp->status) return; if (hci_dev_test_flag(hdev, HCI_SETUP) || hci_dev_test_flag(hdev, HCI_CONFIG)) memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); // {2} } The mark-{1} code directly convert the skb->data to struct hci_rp_read_local_name, without any sanity check. This dedicated struct, hci_rp_read_local_name, owns a large buffer. struct hci_rp_read_local_name { __u8 status; __u8 name[HCI_MAX_NAME_LENGTH]; // 248 bytes } __packed; Think about this: the controller emits the HCI_EV_CMD_COMPLETE event of HCI_OP_READ_LOCAL_NAME opcode to the host, however, with a malformed packet. The size of the crafted packet is smaller than the expected size of struct hci_rp_read_local_name. The driver in the host will allocate sk_buff for this packet and this wrong size packet will be delivered to the vulnerable function hci_cc_read_local_name(). The mark-{2} code hence will trigger Out-Of-Bound Read vulnerability and hence read unexpected kernel heap values into hdev->dev_name. =*=*=*=*=*=*=*=*= BUG EXPLOITS =*=*=*=*=*=*=*=*= To trigger this OOB, the attacker doesn't need any extra privilege. That is because the Linux kernel only ask for the (NET_ADMIN) privilege when users want to wake up the controller and ask for nothing when the controller is being attached. The attacker can attach a malicious controller through the pseudo-TTY device in userspace, which is an equivalence of the VHCI driver. Dislike the previous adv_report functions, this hci_cc_read_local_name() will copy some unexpected heap contents into the hdev->dev_name and can be accessed by any users through HCI management layer. Relevant function call trace is: hci_sock_sendmsg() -> hci_mgmt_cmd() -> read_controller_info() After these, any users can access the hdev->dev_name and get the content from the unexpected OOB read. In my experiment, the exploit can steal memory contents from slab objects in kmalloc-1k cache stably. =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= In last month, Luiz proposed a great solution to fix all possible problems caused by the forced type conversions (https://lore.kernel.org/linux-bluetooth/20210419171257.3865181-3-luiz.dentz@xxxxxxxxx/). Hope the community can settle down this old issue and prevent attackers adopt the vulnerability to leak kernel memory or do other bad things. Regards Lin Ma