xref: /btstack/test/fuzz/fuzz_l2cap_whitebox.c (revision 5576987f3bce50ad7ea167eeb40b7c467df73b54)
1*5576987fSMatthias Ringwald #include <stdint.h>
2*5576987fSMatthias Ringwald #include <stddef.h>
3*5576987fSMatthias Ringwald #include <stdio.h>
4*5576987fSMatthias Ringwald 
5*5576987fSMatthias Ringwald #include <btstack_util.h>
6*5576987fSMatthias Ringwald #include <btstack.h>
7*5576987fSMatthias Ringwald #include <btstack_run_loop_posix.h>
8*5576987fSMatthias Ringwald #include "hci.h"
9*5576987fSMatthias Ringwald 
10*5576987fSMatthias Ringwald static hci_connection_t hci_connection;
11*5576987fSMatthias Ringwald 
12*5576987fSMatthias Ringwald static btstack_linked_list_t hci_connections;
13*5576987fSMatthias Ringwald 
14*5576987fSMatthias Ringwald static btstack_packet_handler_t acl_packet_handler;
15*5576987fSMatthias Ringwald static btstack_packet_handler_t event_packet_handler;
16*5576987fSMatthias Ringwald 
17*5576987fSMatthias Ringwald static uint8_t outgoing_buffer[2000];
18*5576987fSMatthias Ringwald static bool outgoing_reserved;
19*5576987fSMatthias Ringwald 
20*5576987fSMatthias Ringwald void l2cap_setup_test_channels_fuzz(void);
21*5576987fSMatthias Ringwald void l2cap_free_channels_fuzz(void);
22*5576987fSMatthias Ringwald l2cap_channel_t * l2cap_get_dynamic_channel_fuzz(void);
23*5576987fSMatthias Ringwald 
hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler)24*5576987fSMatthias Ringwald void hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler){
25*5576987fSMatthias Ringwald     event_packet_handler = callback_handler->callback;
26*5576987fSMatthias Ringwald }
27*5576987fSMatthias Ringwald 
hci_register_acl_packet_handler(btstack_packet_handler_t handler)28*5576987fSMatthias Ringwald void hci_register_acl_packet_handler(btstack_packet_handler_t handler){
29*5576987fSMatthias Ringwald     acl_packet_handler = handler;
30*5576987fSMatthias Ringwald }
31*5576987fSMatthias Ringwald 
hci_can_send_acl_packet_now(hci_con_handle_t con_handle)32*5576987fSMatthias Ringwald bool hci_can_send_acl_packet_now(hci_con_handle_t con_handle){
33*5576987fSMatthias Ringwald     return true;
34*5576987fSMatthias Ringwald }
35*5576987fSMatthias Ringwald 
hci_connection_for_bd_addr_and_type(const bd_addr_t addr,bd_addr_type_t addr_type)36*5576987fSMatthias Ringwald hci_connection_t * hci_connection_for_bd_addr_and_type(const bd_addr_t addr, bd_addr_type_t addr_type){
37*5576987fSMatthias Ringwald     return &hci_connection;
38*5576987fSMatthias Ringwald }
39*5576987fSMatthias Ringwald 
hci_connection_for_handle(hci_con_handle_t con_handle)40*5576987fSMatthias Ringwald hci_connection_t * hci_connection_for_handle(hci_con_handle_t con_handle){
41*5576987fSMatthias Ringwald     return &hci_connection;
42*5576987fSMatthias Ringwald }
43*5576987fSMatthias Ringwald 
gap_connectable_control(uint8_t enable)44*5576987fSMatthias Ringwald void gap_connectable_control(uint8_t enable){
45*5576987fSMatthias Ringwald }
46*5576987fSMatthias Ringwald 
hci_remote_features_query(hci_con_handle_t con_handle)47*5576987fSMatthias Ringwald void hci_remote_features_query(hci_con_handle_t con_handle){
48*5576987fSMatthias Ringwald }
49*5576987fSMatthias Ringwald 
hci_disconnect_security_block(hci_con_handle_t con_handle)50*5576987fSMatthias Ringwald void hci_disconnect_security_block(hci_con_handle_t con_handle){
51*5576987fSMatthias Ringwald }
52*5576987fSMatthias Ringwald 
gap_request_security_level(hci_con_handle_t con_handle,gap_security_level_t requested_level)53*5576987fSMatthias Ringwald void gap_request_security_level(hci_con_handle_t con_handle, gap_security_level_t requested_level){
54*5576987fSMatthias Ringwald }
55*5576987fSMatthias Ringwald 
gap_set_minimal_service_security_level(gap_security_level_t security_level)56*5576987fSMatthias Ringwald void gap_set_minimal_service_security_level(gap_security_level_t security_level){
57*5576987fSMatthias Ringwald }
58*5576987fSMatthias Ringwald 
hci_connections_get_iterator(btstack_linked_list_iterator_t * it)59*5576987fSMatthias Ringwald void hci_connections_get_iterator(btstack_linked_list_iterator_t *it){
60*5576987fSMatthias Ringwald     btstack_linked_list_iterator_init(it, &hci_connections);
61*5576987fSMatthias Ringwald }
62*5576987fSMatthias Ringwald 
hci_is_le_connection_type(bd_addr_type_t address_type)63*5576987fSMatthias Ringwald bool hci_is_le_connection_type(bd_addr_type_t address_type){
64*5576987fSMatthias Ringwald     switch (address_type){
65*5576987fSMatthias Ringwald         case BD_ADDR_TYPE_LE_PUBLIC:
66*5576987fSMatthias Ringwald         case BD_ADDR_TYPE_LE_RANDOM:
67*5576987fSMatthias Ringwald         case BD_ADDR_TYPE_LE_PUBLIC_IDENTITY:
68*5576987fSMatthias Ringwald         case BD_ADDR_TYPE_LE_RANDOM_IDENTITY:
69*5576987fSMatthias Ringwald             return true;
70*5576987fSMatthias Ringwald         default:
71*5576987fSMatthias Ringwald             return false;
72*5576987fSMatthias Ringwald     }
73*5576987fSMatthias Ringwald }
74*5576987fSMatthias Ringwald 
hci_non_flushable_packet_boundary_flag_supported(void)75*5576987fSMatthias Ringwald bool hci_non_flushable_packet_boundary_flag_supported(void){
76*5576987fSMatthias Ringwald     return true;
77*5576987fSMatthias Ringwald }
78*5576987fSMatthias Ringwald 
hci_automatic_flush_timeout(void)79*5576987fSMatthias Ringwald uint16_t hci_automatic_flush_timeout(void){
80*5576987fSMatthias Ringwald     return 0;
81*5576987fSMatthias Ringwald }
82*5576987fSMatthias Ringwald 
hci_can_send_prepared_acl_packet_now(hci_con_handle_t con_handle)83*5576987fSMatthias Ringwald bool hci_can_send_prepared_acl_packet_now(hci_con_handle_t con_handle) {
84*5576987fSMatthias Ringwald     return true;
85*5576987fSMatthias Ringwald }
86*5576987fSMatthias Ringwald 
hci_can_send_acl_classic_packet_now(void)87*5576987fSMatthias Ringwald bool hci_can_send_acl_classic_packet_now(void){
88*5576987fSMatthias Ringwald     return true;
89*5576987fSMatthias Ringwald }
90*5576987fSMatthias Ringwald 
hci_can_send_acl_le_packet_now(void)91*5576987fSMatthias Ringwald bool hci_can_send_acl_le_packet_now(void){
92*5576987fSMatthias Ringwald     return true;
93*5576987fSMatthias Ringwald }
94*5576987fSMatthias Ringwald 
hci_can_send_command_packet_now(void)95*5576987fSMatthias Ringwald bool hci_can_send_command_packet_now(void){
96*5576987fSMatthias Ringwald     return true;
97*5576987fSMatthias Ringwald }
98*5576987fSMatthias Ringwald 
hci_send_cmd(const hci_cmd_t * cmd,...)99*5576987fSMatthias Ringwald uint8_t hci_send_cmd(const hci_cmd_t * cmd, ...){
100*5576987fSMatthias Ringwald     return ERROR_CODE_SUCCESS;
101*5576987fSMatthias Ringwald }
102*5576987fSMatthias Ringwald 
hci_usable_acl_packet_types(void)103*5576987fSMatthias Ringwald uint16_t hci_usable_acl_packet_types(void){
104*5576987fSMatthias Ringwald     return 0;
105*5576987fSMatthias Ringwald }
106*5576987fSMatthias Ringwald 
hci_get_allow_role_switch(void)107*5576987fSMatthias Ringwald uint8_t hci_get_allow_role_switch(void){
108*5576987fSMatthias Ringwald     return true;
109*5576987fSMatthias Ringwald }
110*5576987fSMatthias Ringwald 
hci_reserve_packet_buffer(void)111*5576987fSMatthias Ringwald void hci_reserve_packet_buffer(void){
112*5576987fSMatthias Ringwald     outgoing_reserved = true;
113*5576987fSMatthias Ringwald }
114*5576987fSMatthias Ringwald 
hci_release_packet_buffer(void)115*5576987fSMatthias Ringwald void hci_release_packet_buffer(void){
116*5576987fSMatthias Ringwald     outgoing_reserved = false;
117*5576987fSMatthias Ringwald }
118*5576987fSMatthias Ringwald 
hci_is_packet_buffer_reserved(void)119*5576987fSMatthias Ringwald bool hci_is_packet_buffer_reserved(void){
120*5576987fSMatthias Ringwald     return outgoing_reserved;
121*5576987fSMatthias Ringwald }
122*5576987fSMatthias Ringwald 
hci_get_outgoing_packet_buffer(void)123*5576987fSMatthias Ringwald uint8_t* hci_get_outgoing_packet_buffer(void){
124*5576987fSMatthias Ringwald     return outgoing_buffer;
125*5576987fSMatthias Ringwald }
126*5576987fSMatthias Ringwald 
hci_send_acl_packet_buffer(int size)127*5576987fSMatthias Ringwald uint8_t hci_send_acl_packet_buffer(int size){
128*5576987fSMatthias Ringwald     outgoing_reserved = false;
129*5576987fSMatthias Ringwald     return ERROR_CODE_SUCCESS;
130*5576987fSMatthias Ringwald }
131*5576987fSMatthias Ringwald 
hci_max_acl_data_packet_length(void)132*5576987fSMatthias Ringwald uint16_t hci_max_acl_data_packet_length(void){
133*5576987fSMatthias Ringwald     return 100;
134*5576987fSMatthias Ringwald }
135*5576987fSMatthias Ringwald 
hci_authentication_active_for_handle(hci_con_handle_t handle)136*5576987fSMatthias Ringwald bool hci_authentication_active_for_handle(hci_con_handle_t handle){
137*5576987fSMatthias Ringwald     return false;
138*5576987fSMatthias Ringwald }
139*5576987fSMatthias Ringwald 
gap_drop_link_key_for_bd_addr(bd_addr_t addr)140*5576987fSMatthias Ringwald void gap_drop_link_key_for_bd_addr(bd_addr_t addr){
141*5576987fSMatthias Ringwald }
142*5576987fSMatthias Ringwald 
gap_get_connection_parameter_range(le_connection_parameter_range_t * range)143*5576987fSMatthias Ringwald void gap_get_connection_parameter_range(le_connection_parameter_range_t * range){
144*5576987fSMatthias Ringwald     memset(range, 0, sizeof(le_connection_parameter_range_t));
145*5576987fSMatthias Ringwald }
146*5576987fSMatthias Ringwald 
gap_authorization_state(hci_con_handle_t con_handle)147*5576987fSMatthias Ringwald authorization_state_t gap_authorization_state(hci_con_handle_t con_handle){
148*5576987fSMatthias Ringwald     return AUTHORIZATION_GRANTED;
149*5576987fSMatthias Ringwald }
150*5576987fSMatthias Ringwald 
151*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_connection_parameter_range_included(le_connection_parameter_range_t * existing_range,uint16_t le_conn_interval_min,uint16_t le_conn_interval_max,uint16_t le_conn_latency,uint16_t le_supervision_timeout)152*5576987fSMatthias Ringwald int gap_connection_parameter_range_included(le_connection_parameter_range_t * existing_range, uint16_t le_conn_interval_min, uint16_t le_conn_interval_max, uint16_t le_conn_latency, uint16_t le_supervision_timeout){
153*5576987fSMatthias Ringwald     return true;
154*5576987fSMatthias Ringwald }
155*5576987fSMatthias Ringwald 
156*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_secure_connection(hci_con_handle_t con_handle)157*5576987fSMatthias Ringwald bool gap_secure_connection(hci_con_handle_t con_handle){
158*5576987fSMatthias Ringwald     return true;
159*5576987fSMatthias Ringwald }
160*5576987fSMatthias Ringwald 
161*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_get_secure_connections_only_mode(void)162*5576987fSMatthias Ringwald bool gap_get_secure_connections_only_mode(void){
163*5576987fSMatthias Ringwald     return false;
164*5576987fSMatthias Ringwald }
165*5576987fSMatthias Ringwald 
166*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_get_connection_type(hci_con_handle_t connection_handle)167*5576987fSMatthias Ringwald gap_connection_type_t gap_get_connection_type(hci_con_handle_t connection_handle){
168*5576987fSMatthias Ringwald     return GAP_CONNECTION_ACL;
169*5576987fSMatthias Ringwald }
170*5576987fSMatthias Ringwald 
171*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_get_security_level(void)172*5576987fSMatthias Ringwald gap_security_level_t gap_get_security_level(void){
173*5576987fSMatthias Ringwald     return LEVEL_4;
174*5576987fSMatthias Ringwald }
175*5576987fSMatthias Ringwald 
176*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_security_level(hci_con_handle_t con_handle)177*5576987fSMatthias Ringwald gap_security_level_t gap_security_level(hci_con_handle_t con_handle){
178*5576987fSMatthias Ringwald     return LEVEL_4;
179*5576987fSMatthias Ringwald }
180*5576987fSMatthias Ringwald 
181*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_get_security_mode(void)182*5576987fSMatthias Ringwald gap_security_mode_t gap_get_security_mode(void){
183*5576987fSMatthias Ringwald     return GAP_SECURITY_MODE_4;
184*5576987fSMatthias Ringwald }
185*5576987fSMatthias Ringwald 
186*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
hci_remote_features_available(hci_con_handle_t handle)187*5576987fSMatthias Ringwald bool hci_remote_features_available(hci_con_handle_t handle){
188*5576987fSMatthias Ringwald     return true;
189*5576987fSMatthias Ringwald }
190*5576987fSMatthias Ringwald 
191*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_ssp_supported_on_both_sides(hci_con_handle_t handle)192*5576987fSMatthias Ringwald bool gap_ssp_supported_on_both_sides(hci_con_handle_t handle){
193*5576987fSMatthias Ringwald     return true;
194*5576987fSMatthias Ringwald }
195*5576987fSMatthias Ringwald 
196*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_encryption_key_size(hci_con_handle_t con_handle)197*5576987fSMatthias Ringwald uint8_t gap_encryption_key_size(hci_con_handle_t con_handle){
198*5576987fSMatthias Ringwald     return 16;
199*5576987fSMatthias Ringwald }
200*5576987fSMatthias Ringwald 
201*5576987fSMatthias Ringwald // TODO: use fuzzer input for level
gap_authenticated(hci_con_handle_t con_handle)202*5576987fSMatthias Ringwald bool gap_authenticated(hci_con_handle_t con_handle){
203*5576987fSMatthias Ringwald     return true;
204*5576987fSMatthias Ringwald }
205*5576987fSMatthias Ringwald 
206*5576987fSMatthias Ringwald // SM
sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler)207*5576987fSMatthias Ringwald void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler){
208*5576987fSMatthias Ringwald }
sm_request_pairing(hci_con_handle_t con_handle)209*5576987fSMatthias Ringwald void sm_request_pairing(hci_con_handle_t con_handle){
210*5576987fSMatthias Ringwald }
211*5576987fSMatthias Ringwald 
fuzzer_l2cap_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)212*5576987fSMatthias Ringwald static void fuzzer_l2cap_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
213*5576987fSMatthias Ringwald 
214*5576987fSMatthias Ringwald     // A Connection Request was received.
215*5576987fSMatthias Ringwald     btstack_assert(false);
216*5576987fSMatthias Ringwald 
217*5576987fSMatthias Ringwald     if (packet_type == HCI_EVENT_PACKET) {
218*5576987fSMatthias Ringwald         if (hci_event_packet_get_type(packet) == L2CAP_EVENT_INCOMING_CONNECTION) {
219*5576987fSMatthias Ringwald             uint16_t l2cap_cid  = l2cap_event_incoming_connection_get_local_cid(packet);
220*5576987fSMatthias Ringwald             l2cap_accept_connection(l2cap_cid);
221*5576987fSMatthias Ringwald         }
222*5576987fSMatthias Ringwald     }
223*5576987fSMatthias Ringwald }
224*5576987fSMatthias Ringwald 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)225*5576987fSMatthias Ringwald int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
226*5576987fSMatthias Ringwald     static int initialized = 0;
227*5576987fSMatthias Ringwald     if (initialized == 0){
228*5576987fSMatthias Ringwald         initialized = 1;
229*5576987fSMatthias Ringwald         btstack_run_loop_init(btstack_run_loop_posix_get_instance());
230*5576987fSMatthias Ringwald         hci_connection.con_handle = 0x0000;
231*5576987fSMatthias Ringwald     }
232*5576987fSMatthias Ringwald 
233*5576987fSMatthias Ringwald     btstack_memory_init();
234*5576987fSMatthias Ringwald 
235*5576987fSMatthias Ringwald     // prepare ACL packet
236*5576987fSMatthias Ringwald     if (size < 1) return 0;
237*5576987fSMatthias Ringwald     uint8_t  pb_or_ps = (data[0] >> 5) & 0x003;            // Packet Boundary field: 0x00-0x03
238*5576987fSMatthias Ringwald     uint16_t cid = L2CAP_CID_SIGNALING;                    // Signaling Packet
239*5576987fSMatthias Ringwald     size -= 1;
240*5576987fSMatthias Ringwald     data += 1;
241*5576987fSMatthias Ringwald     uint8_t packet[1000];
242*5576987fSMatthias Ringwald     uint16_t packet_len;
243*5576987fSMatthias Ringwald     little_endian_store_16(packet, 0, (pb_or_ps << 12) | hci_connection.con_handle);
244*5576987fSMatthias Ringwald     little_endian_store_16(packet, 2, size + 4);
245*5576987fSMatthias Ringwald     little_endian_store_16(packet, 4, size);
246*5576987fSMatthias Ringwald     little_endian_store_16(packet, 6, cid);
247*5576987fSMatthias Ringwald     if (size > (sizeof(packet) - 8)) return 0;
248*5576987fSMatthias Ringwald     memcpy(&packet[8], data, size);
249*5576987fSMatthias Ringwald     packet_len = size + 8;
250*5576987fSMatthias Ringwald 
251*5576987fSMatthias Ringwald     // init hci mock
252*5576987fSMatthias Ringwald     outgoing_reserved = false;
253*5576987fSMatthias Ringwald     hci_connections = (btstack_linked_item_t*) &hci_connection;
254*5576987fSMatthias Ringwald 
255*5576987fSMatthias Ringwald     // init l2cap
256*5576987fSMatthias Ringwald     l2cap_init();
257*5576987fSMatthias Ringwald     l2cap_register_service(&fuzzer_l2cap_handler, 0x1001, 100, LEVEL_0);
258*5576987fSMatthias Ringwald 
259*5576987fSMatthias Ringwald     // deliver test data
260*5576987fSMatthias Ringwald     (*acl_packet_handler)(HCI_ACL_DATA_PACKET, 0, packet, packet_len);
261*5576987fSMatthias Ringwald 
262*5576987fSMatthias Ringwald     if (l2cap_get_dynamic_channel_fuzz() != NULL){
263*5576987fSMatthias Ringwald         // A new channel was created!
264*5576987fSMatthias Ringwald         btstack_assert(false);
265*5576987fSMatthias Ringwald     }
266*5576987fSMatthias Ringwald 
267*5576987fSMatthias Ringwald     // teardown
268*5576987fSMatthias Ringwald     l2cap_unregister_service(0x1001);
269*5576987fSMatthias Ringwald 
270*5576987fSMatthias Ringwald     btstack_memory_deinit();
271*5576987fSMatthias Ringwald 
272*5576987fSMatthias Ringwald     return 0;
273*5576987fSMatthias Ringwald }
274