1 // Copyright © 2022 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 #![no_main] 6 use devices::legacy::Serial; 7 use libc::EFD_NONBLOCK; 8 use libfuzzer_sys::fuzz_target; 9 use std::sync::Arc; 10 use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig, InterruptSourceGroup}; 11 use vm_device::BusDevice; 12 use vmm_sys_util::eventfd::EventFd; 13 14 fuzz_target!(|bytes| { 15 let mut serial = Serial::new_sink( 16 "serial".into(), 17 Arc::new(TestInterrupt::new(EventFd::new(EFD_NONBLOCK).unwrap())), 18 ); 19 20 let mut i = 0; 21 while i < bytes.len() { 22 let choice = bytes.get(i).unwrap_or(&0) % 3; 23 i += 1; 24 25 match choice { 26 0 => { 27 let offset = (bytes.get(i).unwrap_or(&0) % 8) as u64; 28 i += 1; 29 let mut out_bytes = vec![0]; 30 serial.read(0, offset, &mut out_bytes); 31 } 32 1 => { 33 let offset = (bytes.get(i).unwrap_or(&0) % 8) as u64; 34 i += 1; 35 let data = vec![*bytes.get(i).unwrap_or(&0)]; 36 i += 1; 37 serial.write(0, offset, &data); 38 } 39 _ => { 40 let data = vec![*bytes.get(i).unwrap_or(&0)]; 41 i += 1; 42 serial.queue_input_bytes(&data).ok(); 43 } 44 } 45 } 46 }); 47 48 struct TestInterrupt { 49 event_fd: EventFd, 50 } 51 52 impl InterruptSourceGroup for TestInterrupt { 53 fn trigger(&self, _index: InterruptIndex) -> Result<(), std::io::Error> { 54 self.event_fd.write(1) 55 } 56 fn update( 57 &self, 58 _index: InterruptIndex, 59 _config: InterruptSourceConfig, 60 _masked: bool, 61 ) -> Result<(), std::io::Error> { 62 Ok(()) 63 } 64 fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> { 65 Some(self.event_fd.try_clone().unwrap()) 66 } 67 } 68 69 impl TestInterrupt { 70 fn new(event_fd: EventFd) -> Self { 71 TestInterrupt { event_fd } 72 } 73 } 74