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