fuzz, vmm: Avoid infinite loop in CMOS fuzzer

With the addition of the spinning waiting for the exit event to be
received in the CMOS device a regression was introduced into the CMOS
fuzzer. Since there is nothing to receive the event in the fuzzer and
there is nothing to update the bit the that the device is looping on;
introducing an infinite loop.

Use an Option<> type so that when running the device in the fuzzer no
Arc<AtomicBool> is provided effectively disabling the spinning logic.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61165

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
This commit is contained in:
Rob Bradford 2023-08-05 09:43:12 +01:00 committed by Bo Chen
parent 6ee7bfdd50
commit a00d29867c
3 changed files with 12 additions and 10 deletions

View File

@ -25,7 +25,7 @@ pub struct Cmos {
index: u8,
data: [u8; DATA_LEN],
reset_evt: EventFd,
vcpus_kill_signalled: Arc<AtomicBool>,
vcpus_kill_signalled: Option<Arc<AtomicBool>>,
}
impl Cmos {
@ -36,7 +36,7 @@ impl Cmos {
mem_below_4g: u64,
mem_above_4g: u64,
reset_evt: EventFd,
vcpus_kill_signalled: Arc<AtomicBool>,
vcpus_kill_signalled: Option<Arc<AtomicBool>>,
) -> Cmos {
let mut data = [0u8; DATA_LEN];
@ -76,12 +76,14 @@ impl BusDevice for Cmos {
if self.index == 0x8f && data[0] == 0 {
info!("CMOS reset");
self.reset_evt.write(1).unwrap();
// Spin until we are sure the reset_evt has been handled and that when
// we return from the KVM_RUN we will exit rather than re-enter the guest.
while !self.vcpus_kill_signalled.load(Ordering::SeqCst) {
// This is more effective than thread::yield_now() at
// avoiding a priority inversion with the VMM thread
thread::sleep(std::time::Duration::from_millis(1));
if let Some(vcpus_kill_signalled) = self.vcpus_kill_signalled.take() {
// Spin until we are sure the reset_evt has been handled and that when
// we return from the KVM_RUN we will exit rather than re-enter the guest.
while !vcpus_kill_signalled.load(Ordering::SeqCst) {
// This is more effective than thread::yield_now() at
// avoiding a priority inversion with the VMM thread
thread::sleep(std::time::Duration::from_millis(1));
}
}
} else {
self.data[(self.index & INDEX_MASK) as usize] = data[0]

View File

@ -27,7 +27,7 @@ fuzz_target!(|bytes| {
u64::from_le_bytes(below_4g),
u64::from_le_bytes(above_4g),
EventFd::new(EFD_NONBLOCK).unwrap(),
Arc::new(AtomicBool::default()),
None,
);
let mut i = 16;

View File

@ -1630,7 +1630,7 @@ impl DeviceManager {
mem_below_4g,
mem_above_4g,
reset_evt,
vcpus_kill_signalled,
Some(vcpus_kill_signalled),
)));
self.bus_devices