From cfb7db44eb9e5a0bca9a22bfb985252ef74ab251 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 15 Oct 2019 10:06:09 -0700 Subject: fuzz: add USB descriptor parsing fuzzer The new USB descriptor parsing code is a nice candidate for a fuzzer, since it takes an arbitrary stream of bytes as input and parses it. BUG=chromium:987833 TEST=`USE='asan fuzzer' emerge-nami crosvm` Cq-Depend: chromium:1863465 Change-Id: I3bbdbf081e9a9dd590c781467f8bd44fa1dcab64 Signed-off-by: Daniel Verkamp Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1862117 Reviewed-by: Zach Reizner Tested-by: kokoro --- fuzz/Cargo.toml | 5 +++++ fuzz/usb_descriptor_fuzzer.rs | 27 +++++++++++++++++++++++++++ usb_util/src/lib.rs | 4 +++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 fuzz/usb_descriptor_fuzzer.rs diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 5e63344..af6a8b4 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -10,6 +10,7 @@ kernel_loader = { path = "../kernel_loader" } libc = "*" qcow = { path = "../qcow" } sys_util = { path = "../sys_util" } +usb_util = { path = "../usb_util" } # Prevent this from interfering with workspaces [workspace] @@ -23,6 +24,10 @@ path = "block_fuzzer.rs" name = "crosvm_qcow_fuzzer" path = "qcow_fuzzer.rs" +[[bin]] +name = "crosvm_usb_descriptor_fuzzer" +path = "usb_descriptor_fuzzer.rs" + [[bin]] name = "crosvm_zimage_fuzzer" path = "zimage_fuzzer.rs" diff --git a/fuzz/usb_descriptor_fuzzer.rs b/fuzz/usb_descriptor_fuzzer.rs new file mode 100644 index 0000000..d78c8c5 --- /dev/null +++ b/fuzz/usb_descriptor_fuzzer.rs @@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#![no_main] + +use std::panic; +use std::process; +use std::slice; + +use usb_util::parse_usbfs_descriptors; + +#[export_name = "LLVMFuzzerTestOneInput"] +pub fn test_one_input(data: *const u8, size: usize) -> i32 { + // We cannot unwind past ffi boundaries. + panic::catch_unwind(|| { + // Safe because the libfuzzer runtime will guarantee that `data` is at least + // `size` bytes long and that it will be valid for the lifetime of this + // function. + let bytes = unsafe { slice::from_raw_parts(data, size) }; + let _ = parse_usbfs_descriptors(bytes); + }) + .err() + .map(|_| process::abort()); + + 0 +} diff --git a/usb_util/src/lib.rs b/usb_util/src/lib.rs index 2574d90..d793f62 100644 --- a/usb_util/src/lib.rs +++ b/usb_util/src/lib.rs @@ -7,7 +7,9 @@ mod device; mod error; mod types; -pub use self::descriptor::{ConfigDescriptorTree, DeviceDescriptorTree, InterfaceDescriptorTree}; +pub use self::descriptor::{ + parse_usbfs_descriptors, ConfigDescriptorTree, DeviceDescriptorTree, InterfaceDescriptorTree, +}; pub use self::device::{Device, Transfer, TransferStatus}; pub use self::error::{Error, Result}; pub use self::types::{ -- cgit 1.4.1