test/fuzz: setup controller info to allow sending, set conn role as slave, cover more states

This commit is contained in:
Milanka Ringwald 2020-03-10 10:16:10 +01:00
parent a0a4507b35
commit 7d33cb261f
2 changed files with 192 additions and 4 deletions

View File

@ -5338,12 +5338,17 @@ void hci_setup_test_connections_fuzz(void){
// default address: 66:55:44:33:00:01
bd_addr_t addr = { 0x66, 0x55, 0x44, 0x33, 0x00, 0x00};
// setup Controller info
hci_stack->num_cmd_packets = 255;
hci_stack->acl_packets_total_num = 255;
// setup incoming Classic ACL connection with con handle 0x0001, 66:55:44:33:22:01
addr[5] = 0x01;
conn = create_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL);
conn->con_handle = addr[5];
conn->role = HCI_ROLE_SLAVE;
conn->state = RECEIVED_CONNECTION_REQUEST;
conn->sm_connection.sm_role = HCI_ROLE_SLAVE;
// setup incoming Classic SCO connection with con handle 0x0002
addr[5] = 0x02;
@ -5351,6 +5356,7 @@ void hci_setup_test_connections_fuzz(void){
conn->con_handle = addr[5];
conn->role = HCI_ROLE_SLAVE;
conn->state = RECEIVED_CONNECTION_REQUEST;
conn->sm_connection.sm_role = HCI_ROLE_SLAVE;
// setup ready Classic ACL connection with con handle 0x0003
addr[5] = 0x03;
@ -5358,6 +5364,7 @@ void hci_setup_test_connections_fuzz(void){
conn->con_handle = addr[5];
conn->role = HCI_ROLE_SLAVE;
conn->state = OPEN;
conn->sm_connection.sm_role = HCI_ROLE_SLAVE;
// setup ready Classic SCO connection with con handle 0x0004
addr[5] = 0x04;
@ -5365,6 +5372,7 @@ void hci_setup_test_connections_fuzz(void){
conn->con_handle = addr[5];
conn->role = HCI_ROLE_SLAVE;
conn->state = OPEN;
conn->sm_connection.sm_role = HCI_ROLE_SLAVE;
// setup ready LE ACL connection with con handle 0x005 and public address
addr[5] = 0x05;
@ -5372,6 +5380,7 @@ void hci_setup_test_connections_fuzz(void){
conn->con_handle = addr[5];
conn->role = HCI_ROLE_SLAVE;
conn->state = OPEN;
conn->sm_connection.sm_role = HCI_ROLE_SLAVE;
}
void hci_free_connections_fuzz(void){

View File

@ -50,8 +50,37 @@ static const hci_transport_t hci_transport_fuzz = {
static void gatt_client_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
void set_gatt_service_uuid16(gatt_client_service_t * service, const uint8_t *data, size_t size){
service->start_group_handle = 0x0001;
service->end_group_handle = 0xffff;
memset(service->uuid128, 0, 16);
service->uuid16 = big_endian_read_16(data, 0);
}
void set_gatt_service_uuid128(gatt_client_service_t * service, const uint8_t *data, size_t size){
service->start_group_handle = 0x0001;
service->end_group_handle = 0xffff;
service->uuid16 = 0;
memcpy(service->uuid128, data, 16);
}
void set_gatt_characteristic_uuid16(gatt_client_characteristic_t * characteristic, const uint8_t *data, size_t size){
characteristic->start_handle = 0x0001;
characteristic->value_handle = 0x0002;
characteristic->end_handle = 0xffff;
characteristic->uuid16 = big_endian_read_16(data, 0);
memset(characteristic->uuid128, 0, 16);
}
void set_gatt_characteristic_uuid128(gatt_client_characteristic_t * characteristic, const uint8_t *data, size_t size){
characteristic->start_handle = 0x0001;
characteristic->value_handle = 0x0002;
characteristic->end_handle = 0xffff;
characteristic->uuid16 = 0;
memcpy(characteristic->uuid128, data, 16);
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const hci_con_handle_t ble_handle = 0x0005;
static bool gatt_client_initiated = false;
@ -63,13 +92,163 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
hci_setup_test_connections_fuzz();
gatt_client_init();
gatt_client_mtu_enable_auto_negotiation(0);
gatt_client_initiated = true;
}
// TODO: use first byte of random data to pick gatt_client request / set gatt client state
// then, only use dat from second byte as response
gatt_client_discover_primary_services(gatt_client_packet_handler, ble_handle);
// use first byte of random data to pick gatt_client request / set gatt client state
// then, only use data from second byte as response
// prepare test data
if (size < 1) return 0;
uint8_t cmd_type = (data[0] & 0x1F);
size--;
data++;
uint8_t uuid128[16];
uint16_t uuid16;
int offset = 0;
gatt_client_service_t service;
gatt_client_characteristic_t characteristic;
gatt_client_characteristic_descriptor_t descriptor;
switch (cmd_type){
case 1:
gatt_client_discover_primary_services(gatt_client_packet_handler, ble_handle);
break;
case 2:
offset = 2;
if (size < offset) return 0;
uuid16 = big_endian_read_16(data, 0);
gatt_client_discover_primary_services_by_uuid16(gatt_client_packet_handler, ble_handle, uuid16);
break;
case 3:
offset = 16;
if (size < offset) return 0;
memcpy(uuid128, data, 16);
gatt_client_discover_primary_services_by_uuid128(gatt_client_packet_handler, ble_handle, uuid128);
break;
case 4:
offset = 2;
if (size < offset) return 0;
set_gatt_service_uuid16(&service, data, size);
gatt_client_find_included_services_for_service(gatt_client_packet_handler, ble_handle, &service);
break;
case 5:
offset = 2;
if (size < offset) return 0;
set_gatt_service_uuid16(&service, data, size);
gatt_client_discover_characteristics_for_service(gatt_client_packet_handler, ble_handle, &service);
break;
case 6:
offset = 2;
if (size < offset) return 0;
uuid16 = big_endian_read_16(data, 0);
gatt_client_discover_characteristics_for_handle_range_by_uuid16(gatt_client_packet_handler, ble_handle, 0x0001, 0xffff, uuid16);
break;
case 7:
offset = 16;
if (size < offset) return 0;
memcpy(uuid128, data, 16);
gatt_client_discover_characteristics_for_handle_range_by_uuid128(gatt_client_packet_handler, ble_handle, 0x0001, 0xffff, uuid128);
break;
case 8:
offset = 4;
if (size < offset) return 0;
set_gatt_service_uuid16(&service, data, size);
uuid16 = big_endian_read_16(data, 2);
gatt_client_discover_characteristics_for_service_by_uuid16(gatt_client_packet_handler, ble_handle, &service, uuid16);
break;
case 9:
offset = 18;
if (size < offset) return 0;
set_gatt_service_uuid16(&service, data, size);
memcpy(uuid128, data + 2, 16);
gatt_client_discover_characteristics_for_service_by_uuid128(gatt_client_packet_handler, ble_handle, &service, uuid128);
break;
case 10:
offset = 2;
if (size < offset) return 0;
set_gatt_characteristic_uuid16(&characteristic, data, size);
gatt_client_discover_characteristic_descriptors(gatt_client_packet_handler, ble_handle, &characteristic);
break;
case 11:
offset = 2;
if (size < offset) return 0;
set_gatt_characteristic_uuid16(&characteristic, data, size);
gatt_client_read_value_of_characteristic(gatt_client_packet_handler, ble_handle, &characteristic);
break;
case 12:
offset = 2;
if (size < offset) return 0;
set_gatt_characteristic_uuid16(&characteristic, data, size);
gatt_client_read_value_of_characteristics_by_uuid16(gatt_client_packet_handler, ble_handle, characteristic.start_handle, characteristic.end_handle, characteristic.uuid16);
break;
case 13:
offset = 16;
if (size < offset) return 0;
set_gatt_characteristic_uuid128(&characteristic, data, size);
gatt_client_read_value_of_characteristics_by_uuid128(gatt_client_packet_handler, ble_handle, characteristic.start_handle, characteristic.end_handle, characteristic.uuid128);
break;
case 14:
offset = 2;
if (size < offset) return 0;
set_gatt_characteristic_uuid16(&characteristic, data, size);
gatt_client_read_long_value_of_characteristic(gatt_client_packet_handler, ble_handle, &characteristic);
break;
case 15:
offset = 4;
if (size < offset) return 0;
set_gatt_characteristic_uuid16(&characteristic, data, size);
gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(gatt_client_packet_handler, ble_handle, characteristic.value_handle, big_endian_read_16(data, 2));
break;
case 16:
gatt_client_read_multiple_characteristic_values(gatt_client_packet_handler, ble_handle, 0, NULL);
break;
case 17:
gatt_client_write_value_of_characteristic(gatt_client_packet_handler, ble_handle, 5, 0, NULL);
break;
case 18:
gatt_client_write_long_value_of_characteristic(gatt_client_packet_handler, ble_handle, 5, 0, NULL);
break;
case 19:
gatt_client_reliable_write_long_value_of_characteristic(gatt_client_packet_handler, ble_handle, 5, 0, NULL);
break;
case 20:
gatt_client_read_characteristic_descriptor_using_descriptor_handle(gatt_client_packet_handler, ble_handle, 5);
break;
case 21:
gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(gatt_client_packet_handler, ble_handle, 5);
break;
case 22:
gatt_client_write_characteristic_descriptor_using_descriptor_handle(gatt_client_packet_handler, ble_handle, 5, 0, NULL);
break;
case 23:
gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(gatt_client_packet_handler, ble_handle, 5, 0, NULL);
break;
case 24:
offset = 2;
if (size < offset) return 0;
set_gatt_characteristic_uuid16(&characteristic, data, size);
gatt_client_write_client_characteristic_configuration(gatt_client_packet_handler, ble_handle, &characteristic, 1);
break;
case 25:
gatt_client_prepare_write(gatt_client_packet_handler, ble_handle, 5, 0, 0, NULL);
break;
case 26:
gatt_client_prepare_write(gatt_client_packet_handler, ble_handle, 5, 0, 0, NULL);
gatt_client_execute_write(gatt_client_packet_handler, ble_handle);
break;
case 27:
gatt_client_prepare_write(gatt_client_packet_handler, ble_handle, 5, 0, 0, NULL);
gatt_client_cancel_write(gatt_client_packet_handler, ble_handle);
break;
default:
return 0;
}
data += offset;
size -= offset;
// send test response
gatt_client_att_packet_handler_fuzz(ATT_DATA_PACKET, ble_handle, (uint8_t *) data, size);
return 0;