Fwd: Old OOB read bug can cause info leak

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux