blob: 85220004e77705d74ddcbb3ff7f8e5a927653b76 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "usb-cdc-ecm-lib.h"
struct FuzzInput {
const uint8_t* data;
const size_t size;
};
static void UsbGetDescriptors(void* ctx, uint8_t* out_descs_buffer, size_t descs_size,
size_t* out_descs_actual) {
auto input = reinterpret_cast<FuzzInput*>(ctx);
size_t descriptors_length = input->size;
if (descs_size < descriptors_length) {
descriptors_length = descs_size;
}
memcpy(out_descs_buffer, input->data, descriptors_length);
*out_descs_actual = descriptors_length;
}
static size_t UsbGetDescriptorsLength(void* ctx) {
auto input = reinterpret_cast<FuzzInput*>(ctx);
return input->size;
}
static zx_status_t UsbControlIn(void* ctx, uint8_t request_type, uint8_t request, uint16_t value,
uint16_t index, int64_t timeout, uint8_t* out_read_buffer,
size_t read_size, size_t* out_read_actual) {
if (!(request_type & USB_DIR_IN && request == USB_REQ_GET_DESCRIPTOR)) {
return ZX_ERR_INTERNAL;
}
const size_t expected_str_size = sizeof(usb_string_descriptor_t) + ETH_MAC_SIZE * 4;
if (read_size < expected_str_size) {
return ZX_ERR_INVALID_ARGS;
}
*out_read_actual = expected_str_size;
usb_string_descriptor_t usb_str;
usb_str.bLength = expected_str_size;
usb_str.bDescriptorType = USB_DT_STRING;
memcpy(out_read_buffer, &usb_str, sizeof(usb_string_descriptor_t));
uint8_t* ptr = reinterpret_cast<uint8_t*>(out_read_buffer) + sizeof(usb_string_descriptor_t);
for (size_t i = 0; i < ETH_MAC_SIZE; i++) {
memcpy(ptr, "F\0F\0", 4);
ptr += 4;
}
return ZX_OK;
}
usb_protocol_ops_t kFuzzedUsbProtocolOps = {
.control_in = UsbControlIn,
.get_descriptors_length = UsbGetDescriptorsLength,
.get_descriptors = UsbGetDescriptors,
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
FuzzInput input = {.data = Data, .size = Size};
usb_protocol_t proto = {.ops = &kFuzzedUsbProtocolOps, .ctx = &input};
usb_endpoint_descriptor_t* int_ep = nullptr;
usb_endpoint_descriptor_t* tx_ep = nullptr;
usb_endpoint_descriptor_t* rx_ep = nullptr;
usb_interface_descriptor_t* default_ifc = nullptr;
usb_interface_descriptor_t* data_ifc = nullptr;
ecm_ctx_t ecm_ctx;
ecm_ctx.usb = proto;
usb_desc_iter_t iter;
if (ZX_OK != usb_desc_iter_init(&proto, &iter)) {
return 0;
}
parse_usb_descriptor(&iter, &int_ep, &tx_ep, &rx_ep, &default_ifc, &data_ifc, &ecm_ctx);
usb_desc_iter_release(&iter);
return 0;
}