mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-25 10:43:44 +00:00
fuzz: Add msc fuzz harness
This commit is contained in:
parent
aedae6201b
commit
92b5f2d2e8
29
fuzz/device/msc/CMakeLists.txt
Normal file
29
fuzz/device/msc/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||
|
||||
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
|
||||
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
project(${PROJECT})
|
||||
|
||||
# Checks this example is valid for the family and initializes the project
|
||||
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Configure compilation flags and libraries for the example... see the corresponding function
|
||||
# in hw/bsp/FAMILY/family.cmake for details.
|
||||
family_configure_device_example(${PROJECT})
|
12
fuzz/device/msc/Makefile
Normal file
12
fuzz/device/msc/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
include ../../../tools/top.mk
|
||||
include ../../make.mk
|
||||
|
||||
INC += \
|
||||
src \
|
||||
$(TOP)/hw \
|
||||
|
||||
# Example source
|
||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.c))
|
||||
SRC_CXX += $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.cc))
|
||||
|
||||
include ../../rules.mk
|
1
fuzz/device/msc/skip.txt
Normal file
1
fuzz/device/msc/skip.txt
Normal file
@ -0,0 +1 @@
|
||||
mcu:SAMD11
|
62
fuzz/device/msc/src/fuzz.cc
Normal file
62
fuzz/device/msc/src/fuzz.cc
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Nathaniel Brough
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <fuzzer/FuzzedDataProvider.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "class/cdc/cdc_device.h"
|
||||
#include "fuzz/fuzz.h"
|
||||
#include "tusb.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||
//--------------------------------------------------------------------+
|
||||
#define FUZZ_ITERATIONS 500
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
FuzzedDataProvider provider(Data, Size);
|
||||
std::vector<uint8_t> callback_data = provider.ConsumeBytes<uint8_t>(
|
||||
provider.ConsumeIntegralInRange<size_t>(0, Size));
|
||||
fuzz_init(callback_data.data(), callback_data.size());
|
||||
// init device stack on configured roothub port
|
||||
tud_init(BOARD_TUD_RHPORT);
|
||||
|
||||
for (int i = 0; i < FUZZ_ITERATIONS; i++) {
|
||||
if (provider.remaining_bytes() == 0) {
|
||||
return 0;
|
||||
}
|
||||
tud_int_handler(provider.ConsumeIntegral<uint8_t>());
|
||||
tud_task(); // tinyusb device task
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
114
fuzz/device/msc/src/tusb_config.h
Normal file
114
fuzz/device/msc/src/tusb_config.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Nathaniel Brough
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Board Specific Configuration
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// RHPort max operational speed can defined by board.mk
|
||||
#ifndef BOARD_TUD_MAX_SPEED
|
||||
#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Common Configuration
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// defined by compiler flags for flexibility
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
// Default is max speed that hardware controller could support with on-chip PHY
|
||||
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
* e.g
|
||||
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||
*/
|
||||
#ifndef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_CDC 0
|
||||
#define CFG_TUD_MSC 1
|
||||
#define CFG_TUD_HID 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
// CDC FIFO size of TX and RX
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
// CDC Endpoint transfer buffer size, more is faster
|
||||
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
// MSC Buffer size of Device Mass storage
|
||||
#define CFG_TUD_MSC_EP_BUFSIZE 512
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
224
fuzz/device/msc/src/usb_descriptors.cc
Normal file
224
fuzz/device/msc/src/usb_descriptors.cc
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Nathaniel Brough
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
/* A combination of interfaces must have a unique product id, since PC will save
|
||||
* device driver after the first plug.
|
||||
* Auto ProductID layout's Bitmap:
|
||||
* [MSB] HID | MSC | CDC [LSB]
|
||||
*/
|
||||
#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n))
|
||||
#define USB_PID \
|
||||
(0x4000 | _PID_MAP(MSC, 0) | _PID_MAP(HID, 1) | _PID_MAP(MIDI, 2) | \
|
||||
_PID_MAP(VENDOR, 3))
|
||||
#define USB_VID 0xCafe
|
||||
#define USB_BCD 0x0200
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Invoked when received GET DEVICE DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
uint8_t const *tud_descriptor_device_cb(void) {
|
||||
static tusb_desc_device_t const desc_device = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = USB_BCD,
|
||||
|
||||
// Use Interface Association Descriptor (IAD) for CDC
|
||||
// As required by USB Specs IAD's subclass must be common class (2) and
|
||||
// protocol must be IAD (1)
|
||||
.bDeviceClass = TUSB_CLASS_MISC,
|
||||
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
|
||||
.idVendor = USB_VID,
|
||||
.idProduct = USB_PID,
|
||||
.bcdDevice = 0x0100,
|
||||
|
||||
.iManufacturer = 0x01,
|
||||
.iProduct = 0x02,
|
||||
.iSerialNumber = 0x03,
|
||||
|
||||
.bNumConfigurations = 0x01};
|
||||
|
||||
return (uint8_t const *)&desc_device;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Configuration Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
enum { ITF_NUM_MSC = 0, ITF_NUM_TOTAL };
|
||||
|
||||
#define EPNUM_MSC_OUT 0x05
|
||||
#define EPNUM_MSC_IN 0x85
|
||||
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN)
|
||||
|
||||
// full speed configuration
|
||||
uint8_t const desc_fs_configuration[] = {
|
||||
// Config number, interface count, string index, total length, attribute,
|
||||
// power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||
|
||||
// Interface number, string index, EP Out & EP In address, EP size
|
||||
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 4, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
|
||||
};
|
||||
|
||||
#if TUD_OPT_HIGH_SPEED
|
||||
// Per USB specs: high speed capable device must report device_qualifier and
|
||||
// other_speed_configuration
|
||||
|
||||
// high speed configuration
|
||||
uint8_t const desc_hs_configuration[] = {
|
||||
// Config number, interface count, string index, total length, attribute,
|
||||
// power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||
|
||||
// Interface number, string index, EP Out & EP In address, EP size
|
||||
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 4, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
|
||||
};
|
||||
|
||||
// other speed configuration
|
||||
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
|
||||
|
||||
// device qualifier is mostly similar to device descriptor since we don't change
|
||||
// configuration based on speed
|
||||
tusb_desc_device_qualifier_t const desc_device_qualifier = {
|
||||
.bLength = sizeof(tusb_desc_device_qualifier_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
||||
.bcdUSB = USB_BCD,
|
||||
|
||||
.bDeviceClass = TUSB_CLASS_MISC,
|
||||
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
.bNumConfigurations = 0x01,
|
||||
.bReserved = 0x00};
|
||||
|
||||
// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
|
||||
// Application return pointer to descriptor, whose contents must exist long
|
||||
// enough for transfer to complete. device_qualifier descriptor describes
|
||||
// information about a high-speed capable device that would change if the device
|
||||
// were operating at the other speed. If not highspeed capable stall this
|
||||
// request.
|
||||
uint8_t const *tud_descriptor_device_qualifier_cb(void) {
|
||||
return (uint8_t const *)&desc_device_qualifier;
|
||||
}
|
||||
|
||||
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
|
||||
// Application return pointer to descriptor, whose contents must exist long
|
||||
// enough for transfer to complete Configuration descriptor in the other speed
|
||||
// e.g if high speed then this is for full speed and vice versa
|
||||
uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
|
||||
(void)index; // for multiple configurations
|
||||
|
||||
// if link speed is high return fullspeed config, and vice versa
|
||||
// Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG
|
||||
memcpy(desc_other_speed_config,
|
||||
(tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration
|
||||
: desc_hs_configuration,
|
||||
CONFIG_TOTAL_LEN);
|
||||
|
||||
desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG;
|
||||
|
||||
return desc_other_speed_config;
|
||||
}
|
||||
|
||||
#endif // highspeed
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
(void)index; // for multiple configurations
|
||||
|
||||
#if TUD_OPT_HIGH_SPEED
|
||||
// Although we are highspeed, host may be fullspeed.
|
||||
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration
|
||||
: desc_fs_configuration;
|
||||
#else
|
||||
return desc_fs_configuration;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// String Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// array of pointer to string descriptors
|
||||
char const *string_desc_arr[] = {
|
||||
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
|
||||
"TinyUSB", // 1: Manufacturer
|
||||
"TinyUSB Device", // 2: Product
|
||||
"123456789012", // 3: Serials, should use chip ID
|
||||
"TinyUSB MSC", // 4: MSC Interface
|
||||
|
||||
};
|
||||
|
||||
static uint16_t _desc_str[32];
|
||||
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
// Application return pointer to descriptor, whose contents must exist long
|
||||
// enough for transfer to complete
|
||||
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
(void)langid;
|
||||
|
||||
uint8_t chr_count;
|
||||
|
||||
if (index == 0) {
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
chr_count = 1;
|
||||
} else {
|
||||
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||
|
||||
if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])))
|
||||
return NULL;
|
||||
|
||||
const char *str = string_desc_arr[index];
|
||||
|
||||
// Cap at max char
|
||||
chr_count = (uint8_t)strlen(str);
|
||||
if (chr_count > 31)
|
||||
chr_count = 31;
|
||||
|
||||
// Convert ASCII string into UTF-16
|
||||
for (uint8_t i = 0; i < chr_count; i++) {
|
||||
_desc_str[1 + i] = str[i];
|
||||
}
|
||||
}
|
||||
|
||||
// first byte is length (including header), second byte is string type
|
||||
_desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
|
||||
|
||||
return _desc_str;
|
||||
}
|
162
fuzz/msc_fuzz.cc
Normal file
162
fuzz/msc_fuzz.cc
Normal file
@ -0,0 +1,162 @@
|
||||
#include "fuzz/fuzz_private.h"
|
||||
#include "tusb.h"
|
||||
#include <cassert>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
|
||||
#if CFG_TUD_MSC==1
|
||||
|
||||
// Whether host does safe eject.
|
||||
// tud_msc_get_maxlun_cb returns a uint8_t so the max logical units that are
|
||||
// allowed is 255, so we need to keep track of 255 fuzzed logical units.
|
||||
static std::array<bool, std::numeric_limits<uint8_t>::max()> ejected = {false};
|
||||
|
||||
extern "C" {
|
||||
// Invoked when received SCSI_CMD_INQUIRY
|
||||
// Application fill vendor id, product id and revision with string up to 8, 16,
|
||||
// 4 characters respectively
|
||||
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8],
|
||||
uint8_t product_id[16], uint8_t product_rev[4]) {
|
||||
(void)lun;
|
||||
assert(_fuzz_data_provider.has_value());
|
||||
|
||||
std::string vid = _fuzz_data_provider->ConsumeBytesAsString(8);
|
||||
std::string pid = _fuzz_data_provider->ConsumeBytesAsString(16);
|
||||
std::string rev = _fuzz_data_provider->ConsumeBytesAsString(4);
|
||||
|
||||
memcpy(vendor_id, vid.c_str(), strlen(vid.c_str()));
|
||||
memcpy(product_id, pid.c_str(), strlen(pid.c_str()));
|
||||
memcpy(product_rev, rev.c_str(), strlen(rev.c_str()));
|
||||
}
|
||||
|
||||
// Invoked when received Test Unit Ready command.
|
||||
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
|
||||
// RAM disk is ready until ejected
|
||||
if (ejected[lun]) {
|
||||
// Additional Sense 3A-00 is NOT_FOUND
|
||||
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _fuzz_data_provider->ConsumeBool();
|
||||
}
|
||||
|
||||
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and
|
||||
// SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size Application update
|
||||
// block count and block size
|
||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count,
|
||||
uint16_t *block_size) {
|
||||
(void)lun;
|
||||
*block_count = _fuzz_data_provider->ConsumeIntegral<uint32_t>();
|
||||
*block_size = _fuzz_data_provider->ConsumeIntegral<uint16_t>();
|
||||
}
|
||||
|
||||
// Invoked when received Start Stop Unit command
|
||||
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start,
|
||||
bool load_eject) {
|
||||
(void)power_condition;
|
||||
assert(_fuzz_data_provider.has_value());
|
||||
|
||||
if (load_eject) {
|
||||
if (start) {
|
||||
// load disk storage
|
||||
} else {
|
||||
// unload disk storage
|
||||
ejected[lun] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return _fuzz_data_provider->ConsumeBool();
|
||||
}
|
||||
|
||||
// Callback invoked when received READ10 command.
|
||||
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
||||
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset,
|
||||
void *buffer, uint32_t bufsize) {
|
||||
assert(_fuzz_data_provider.has_value());
|
||||
(void)lun;
|
||||
(void)lba;
|
||||
(void)offset;
|
||||
|
||||
std::vector<uint8_t> consumed_buffer = _fuzz_data_provider->ConsumeBytes<uint8_t>(
|
||||
_fuzz_data_provider->ConsumeIntegralInRange<uint32_t>(0, bufsize));
|
||||
memcpy(buffer, consumed_buffer.data(), consumed_buffer.size());
|
||||
|
||||
// Sometimes return an error code;
|
||||
if (_fuzz_data_provider->ConsumeBool()) {
|
||||
return _fuzz_data_provider->ConsumeIntegralInRange(
|
||||
std::numeric_limits<int32_t>::min(), -1);
|
||||
}
|
||||
|
||||
return consumed_buffer.size();
|
||||
}
|
||||
|
||||
bool tud_msc_is_writable_cb(uint8_t lun) {
|
||||
assert(_fuzz_data_provider.has_value());
|
||||
(void)lun;
|
||||
return _fuzz_data_provider->ConsumeBool();
|
||||
}
|
||||
|
||||
// Callback invoked when received WRITE10 command.
|
||||
// Process data in buffer to disk's storage and return number of written bytes
|
||||
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset,
|
||||
uint8_t *buffer, uint32_t bufsize) {
|
||||
// Ignore these as they are outputs and don't affect the return value.
|
||||
(void)lun;
|
||||
(void)lba;
|
||||
(void)offset;
|
||||
(void)buffer;
|
||||
assert(_fuzz_data_provider.has_value());
|
||||
|
||||
// -ve error codes -> bufsize.
|
||||
return _fuzz_data_provider->ConsumeIntegralInRange<int32_t>(
|
||||
std::numeric_limits<int32_t>::min(), bufsize);
|
||||
}
|
||||
|
||||
// Callback invoked when received an SCSI command not in built-in list below
|
||||
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
||||
// - READ10 and WRITE10 has their own callbacks
|
||||
int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer,
|
||||
uint16_t bufsize) {
|
||||
(void)buffer;
|
||||
(void)bufsize;
|
||||
assert(_fuzz_data_provider.has_value());
|
||||
|
||||
switch (scsi_cmd[0]) {
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
break;
|
||||
case SCSI_CMD_INQUIRY:
|
||||
break;
|
||||
case SCSI_CMD_MODE_SELECT_6:
|
||||
break;
|
||||
case SCSI_CMD_MODE_SENSE_6:
|
||||
break;
|
||||
case SCSI_CMD_START_STOP_UNIT:
|
||||
break;
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
break;
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
break;
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
break;
|
||||
case SCSI_CMD_READ_FORMAT_CAPACITY:
|
||||
break;
|
||||
case SCSI_CMD_READ_10:
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
break;
|
||||
default:
|
||||
// Set Sense = Invalid Command Operation
|
||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||
return _fuzz_data_provider->ConsumeIntegralInRange<int32_t>(
|
||||
std::numeric_limits<int32_t>::min(), -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user