xref: /cloud-hypervisor/fuzz/fuzz_targets/serial.rs (revision 19d36c765fdf00be749d95b3e61028bc302d6d73)
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