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 None, 19 ); 20 21 let mut i = 0; 22 while i < bytes.len() { 23 let choice = bytes.get(i).unwrap_or(&0) % 3; 24 i += 1; 25 26 match choice { 27 0 => { 28 let offset = (bytes.get(i).unwrap_or(&0) % 8) as u64; 29 i += 1; 30 let mut out_bytes = vec![0]; 31 serial.read(0, offset, &mut out_bytes); 32 } 33 1 => { 34 let offset = (bytes.get(i).unwrap_or(&0) % 8) as u64; 35 i += 1; 36 let data = vec![*bytes.get(i).unwrap_or(&0)]; 37 i += 1; 38 serial.write(0, offset, &data); 39 } 40 _ => { 41 let data = vec![*bytes.get(i).unwrap_or(&0)]; 42 i += 1; 43 serial.queue_input_bytes(&data).ok(); 44 } 45 } 46 } 47 }); 48 49 struct TestInterrupt { 50 event_fd: EventFd, 51 } 52 53 impl InterruptSourceGroup for TestInterrupt { 54 fn trigger(&self, _index: InterruptIndex) -> Result<(), std::io::Error> { 55 self.event_fd.write(1) 56 } 57 fn update( 58 &self, 59 _index: InterruptIndex, 60 _config: InterruptSourceConfig, 61 _masked: bool, 62 ) -> Result<(), std::io::Error> { 63 Ok(()) 64 } 65 fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> { 66 Some(self.event_fd.try_clone().unwrap()) 67 } 68 } 69 70 impl TestInterrupt { 71 fn new(event_fd: EventFd) -> Self { 72 TestInterrupt { event_fd } 73 } 74 } 75