1 #include <stdint.h>
2 #include <stddef.h>
3 #include <stdio.h>
4
5 #include <btstack_util.h>
6 #include <btstack.h>
7 #include <btstack_run_loop_posix.h>
8 #include "hci.h"
9
10 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size);
11
hci_transport_fuzz_set_baudrate(uint32_t baudrate)12 static int hci_transport_fuzz_set_baudrate(uint32_t baudrate){
13 return 0;
14 }
15
hci_transport_fuzz_can_send_now(uint8_t packet_type)16 static int hci_transport_fuzz_can_send_now(uint8_t packet_type){
17 return 1;
18 }
19
hci_transport_fuzz_send_packet(uint8_t packet_type,uint8_t * packet,int size)20 static int hci_transport_fuzz_send_packet(uint8_t packet_type, uint8_t * packet, int size){
21 return 0;
22 }
23
hci_transport_fuzz_init(const void * transport_config)24 static void hci_transport_fuzz_init(const void * transport_config){
25 }
26
hci_transport_fuzz_open(void)27 static int hci_transport_fuzz_open(void){
28 return 0;
29 }
30
hci_transport_fuzz_close(void)31 static int hci_transport_fuzz_close(void){
32 return 0;
33 }
34
hci_transport_fuzz_register_packet_handler(void (* handler)(uint8_t packet_type,uint8_t * packet,uint16_t size))35 static void hci_transport_fuzz_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
36 packet_handler = handler;
37 }
38
39 static const hci_transport_t hci_transport_fuzz = {
40 /* const char * name; */ "FUZZ",
41 /* void (*init) (const void *transport_config); */ &hci_transport_fuzz_init,
42 /* int (*open)(void); */ &hci_transport_fuzz_open,
43 /* int (*close)(void); */ &hci_transport_fuzz_close,
44 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_fuzz_register_packet_handler,
45 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_fuzz_can_send_now,
46 /* int (*send_packet)(...); */ &hci_transport_fuzz_send_packet,
47 /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_fuzz_set_baudrate,
48 /* void (*reset_link)(void); */ NULL,
49 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL,
50 };
51
l2cap_packet_handler(uint8_t packet_type,uint8_t * packet,uint16_t size)52 static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){
53 switch (packet_type) {
54 case HCI_EVENT_PACKET:
55 break;
56 case HCI_SCO_DATA_PACKET:
57 break;
58 case HCI_ACL_DATA_PACKET:
59 break;
60 default:
61 break;
62 }
63 }
64
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)65 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
66 static int initialized = 0;
67 if (initialized == 0){
68 initialized = 1;
69 btstack_memory_init();
70 btstack_run_loop_init(btstack_run_loop_posix_get_instance());
71 }
72
73 // prepare test data
74 if (size < 3) return 0;
75 uint8_t packet_type = (data[0] & 3) + 1; // only 1-4
76 uint16_t connection_handle = ((data[0] >> 2) & 0x07); // 0x0000 - 0x0007
77 uint8_t pb_or_ps = (data[0] >> 5) & 0x003; // 0x00-0x03
78 size--;
79 data++;
80 uint8_t packet[1000];
81 uint16_t packet_len;
82 switch (packet_type){
83 case HCI_EVENT_PACKET:
84 packet[0] = data[0];
85 size--;
86 data++;
87 if (size > 255) return 0;
88 packet[1] = size;
89 memcpy(&packet[2], data, size);
90 packet_len = size + 2;
91 // avoid assert on packet buffer reserved
92 if (packet[0] == HCI_EVENT_TRANSPORT_PACKET_SENT){
93 return 0;
94 }
95 break;
96 case HCI_SCO_DATA_PACKET:
97 little_endian_store_16(packet, 0, (pb_or_ps << 12) | connection_handle);
98 if (size > 255) return 0;
99 packet[2] = size;
100 memcpy(&packet[3], data, size);
101 packet_len = size + 3;
102 break;
103 case HCI_ACL_DATA_PACKET:
104 little_endian_store_16(packet, 0, (pb_or_ps << 12) | connection_handle);
105 little_endian_store_16(packet, 2, size);
106 if (size > (sizeof(packet) - 4)) return 0;
107 memcpy(&packet[4], data, size);
108 packet_len = size + 4;
109 break;
110 default:
111 return 0;
112 }
113
114 // init hci
115 hci_init(&hci_transport_fuzz, NULL);
116 hci_setup_test_connections_fuzz();
117
118 // deliver test data
119 (*packet_handler)(packet_type, packet, packet_len);
120
121 // teardown
122 hci_free_connections_fuzz();
123 return 0;
124 }
125