diff options
Diffstat (limited to 'executor/common_linux.h')
| -rw-r--r-- | executor/common_linux.h | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index 39a687e36..10f693815 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -2586,11 +2586,21 @@ struct hci_dev_req { uint32 dev_opt; }; -struct vhci_vendor_pkt { +struct vhci_vendor_pkt_request { uint8 type; uint8 opcode; - uint16 id; -}; +} __attribute__((packed)); + +struct vhci_pkt { + uint8 type; + union { + struct { + uint8 opcode; + uint16 id; + } __attribute__((packed)) vendor_pkt; + struct hci_command_hdr command_hdr; + }; +} __attribute__((packed)); #define HCIDEVUP _IOW('H', 201, int) #define HCISETSCAN _IOW('H', 221, int) @@ -2718,6 +2728,9 @@ static void* event_thread(void* arg) #define HCI_HANDLE_1 200 #define HCI_HANDLE_2 201 +#define HCI_PRIMARY 0 +#define HCI_OP_RESET 0x0c03 + static void initialize_vhci() { #if SYZ_EXECUTOR @@ -2741,25 +2754,38 @@ static void initialize_vhci() close(vhci_fd); vhci_fd = kVhciFd; - struct vhci_vendor_pkt vendor_pkt; - if (read(vhci_fd, &vendor_pkt, sizeof(vendor_pkt)) != sizeof(vendor_pkt)) - fail("read failed"); + struct vhci_vendor_pkt_request vendor_pkt_req = {HCI_VENDOR_PKT, HCI_PRIMARY}; + if (write(vhci_fd, &vendor_pkt_req, sizeof(vendor_pkt_req)) != sizeof(vendor_pkt_req)) + fail("vendor_pkt_req write failed"); + + struct vhci_pkt vhci_pkt; + if (read(vhci_fd, &vhci_pkt, sizeof(vhci_pkt)) != sizeof(vhci_pkt)) + fail("vhci_pkt read failed"); + + if (vhci_pkt.type == HCI_COMMAND_PKT && vhci_pkt.command_hdr.opcode == HCI_OP_RESET) { + char response[1] = {0}; + hci_send_event_cmd_complete(vhci_fd, HCI_OP_RESET, response, sizeof(response)); + + if (read(vhci_fd, &vhci_pkt, sizeof(vhci_pkt)) != sizeof(vhci_pkt)) + fail("vhci_pkt read failed"); + } - if (vendor_pkt.type != HCI_VENDOR_PKT) + if (vhci_pkt.type != HCI_VENDOR_PKT) fail("wrong response packet"); - debug("hci dev id: %x\n", vendor_pkt.id); + int dev_id = vhci_pkt.vendor_pkt.id; + debug("hci dev id: %x\n", dev_id); pthread_t th; if (pthread_create(&th, NULL, event_thread, NULL)) fail("pthread_create failed"); // Bring hci device up - int ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id); + int ret = ioctl(hci_sock, HCIDEVUP, dev_id); if (ret) { if (errno == ERFKILL) { rfkill_unblock_all(); - ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id); + ret = ioctl(hci_sock, HCIDEVUP, dev_id); } if (ret && errno != EALREADY) @@ -2768,7 +2794,7 @@ static void initialize_vhci() // Activate page scanning mode which is required to fake a connection. struct hci_dev_req dr = {0}; - dr.dev_id = vendor_pkt.id; + dr.dev_id = dev_id; dr.dev_opt = SCAN_PAGE; if (ioctl(hci_sock, HCISETSCAN, &dr)) fail("ioctl(HCISETSCAN) failed"); |
