Skip to content

Commit 18367e6

Browse files
committed
fix: store bitvec as Vec<bool> to prevent fuzzer crashes
When the fuzzer generates an invalid bitvec state, the serde code crashes with an assertion error. To avoid these crashes, just store it as a plain Vec<bool> as we don't expect these vecs to be too big (for a 10GB hotpluggable area with 2MiB blocks it would require 5kB for the Vec<bool> compared to 640B with BitVec). Signed-off-by: Riccardo Mancini <[email protected]>
1 parent 0c156c4 commit 18367e6

File tree

3 files changed

+18
-14
lines changed

3 files changed

+18
-14
lines changed

src/vmm/src/devices/virtio/mem/persist.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct VirtioMemState {
2828
usable_region_size: u64,
2929
requested_size: u64,
3030
slot_size: usize,
31-
plugged_blocks: BitVec,
31+
plugged_blocks: Vec<bool>,
3232
}
3333

3434
#[derive(Debug)]
@@ -62,7 +62,7 @@ impl Persist<'_> for VirtioMem {
6262
region_size: self.config.region_size,
6363
block_size: self.config.block_size,
6464
usable_region_size: self.config.usable_region_size,
65-
plugged_blocks: self.plugged_blocks.clone(),
65+
plugged_blocks: self.plugged_blocks.iter().by_vals().collect(),
6666
requested_size: self.config.requested_size,
6767
slot_size: self.slot_size,
6868
}
@@ -79,12 +79,14 @@ impl Persist<'_> for VirtioMem {
7979
FIRECRACKER_MAX_QUEUE_SIZE,
8080
)?;
8181

82+
let plugged_blocks = BitVec::from_iter(state.plugged_blocks.iter());
83+
8284
let config = virtio_mem_config {
8385
addr: state.addr,
8486
region_size: state.region_size,
8587
block_size: state.block_size,
8688
usable_region_size: state.usable_region_size,
87-
plugged_size: usize_to_u64(state.plugged_blocks.count_ones()) * state.block_size,
89+
plugged_size: usize_to_u64(plugged_blocks.count_ones()) * state.block_size,
8890
requested_size: state.requested_size,
8991
..Default::default()
9092
};
@@ -94,7 +96,7 @@ impl Persist<'_> for VirtioMem {
9496
queues,
9597
config,
9698
state.slot_size,
97-
state.plugged_blocks.clone(),
99+
plugged_blocks,
98100
)?;
99101
virtio_mem.set_avail_features(state.virtio_state.avail_features);
100102
virtio_mem.set_acked_features(state.virtio_state.acked_features);
@@ -119,7 +121,10 @@ mod tests {
119121
assert_eq!(state.region_size, dev.config.region_size);
120122
assert_eq!(state.block_size, dev.config.block_size);
121123
assert_eq!(state.usable_region_size, dev.config.usable_region_size);
122-
assert_eq!(state.plugged_blocks, dev.plugged_blocks);
124+
assert_eq!(
125+
state.plugged_blocks.iter().collect::<BitVec>(),
126+
dev.plugged_blocks
127+
);
123128
assert_eq!(state.requested_size, dev.config.requested_size);
124129
assert_eq!(state.slot_size, dev.slot_size);
125130
}

src/vmm/src/persist.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,6 @@ fn send_uffd_handshake(
571571
mod tests {
572572
use std::os::unix::net::UnixListener;
573573

574-
use bitvec::vec::BitVec;
575574
use vmm_sys_util::tempfile::TempFile;
576575

577576
use super::*;
@@ -695,7 +694,7 @@ mod tests {
695694
base_address: 0,
696695
size: 0x20000,
697696
region_type: GuestRegionType::Dram,
698-
plugged: BitVec::repeat(true, 1),
697+
plugged: vec![true],
699698
}],
700699
};
701700

src/vmm/src/vstate/memory.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ impl GuestRegionMmapExt {
240240
slot_size,
241241
region_type: state.region_type,
242242
slot_from,
243-
plugged: Mutex::new(state.plugged.clone()),
243+
plugged: Mutex::new(BitVec::from_iter(state.plugged.iter())),
244244
})
245245
}
246246

@@ -596,7 +596,7 @@ pub struct GuestMemoryRegionState {
596596
/// Region type
597597
pub region_type: GuestRegionType,
598598
/// Plugged/unplugged status of each slot
599-
pub plugged: BitVec,
599+
pub plugged: Vec<bool>,
600600
}
601601

602602
/// Describes guest memory regions and their snapshot file mappings.
@@ -625,7 +625,7 @@ impl GuestMemoryExtension for GuestMemoryMmap {
625625
base_address: region.start_addr().0,
626626
size: u64_to_usize(region.len()),
627627
region_type: region.region_type,
628-
plugged: region.plugged.lock().unwrap().clone(),
628+
plugged: region.plugged.lock().unwrap().iter().by_vals().collect(),
629629
});
630630
});
631631
guest_memory_state
@@ -997,13 +997,13 @@ mod tests {
997997
base_address: 0,
998998
size: page_size,
999999
region_type: GuestRegionType::Dram,
1000-
plugged: BitVec::repeat(true, 1),
1000+
plugged: vec![true],
10011001
},
10021002
GuestMemoryRegionState {
10031003
base_address: page_size as u64 * 2,
10041004
size: page_size,
10051005
region_type: GuestRegionType::Dram,
1006-
plugged: BitVec::repeat(true, 1),
1006+
plugged: vec![true],
10071007
},
10081008
],
10091009
};
@@ -1026,13 +1026,13 @@ mod tests {
10261026
base_address: 0,
10271027
size: page_size * 3,
10281028
region_type: GuestRegionType::Dram,
1029-
plugged: BitVec::repeat(true, 1),
1029+
plugged: vec![true],
10301030
},
10311031
GuestMemoryRegionState {
10321032
base_address: page_size as u64 * 4,
10331033
size: page_size * 3,
10341034
region_type: GuestRegionType::Dram,
1035-
plugged: BitVec::repeat(true, 1),
1035+
plugged: vec![true],
10361036
},
10371037
],
10381038
};

0 commit comments

Comments
 (0)