rust-vmm / vm-memory

Virtual machine's guest memory crate
Apache License 2.0
299 stars 97 forks source link

Missing Divide-by-Zero Check #268

Closed JonathanWoollett-Light closed 9 months ago

JonathanWoollett-Light commented 9 months ago

From @y-x41

While reviewing the vm-memory Rust crate, it was noticed that the function AtomicBitmap::new() does not properly check the page_size parameter for being zero. As this parameter is being used as a divisor within the function, a value of zero leads to a Divide-by-zero CPU fault resulting in an application panic. The below listing shows the affected code snippet.

While the function is solely used within the rust-vmm ecosystem with valid page_size values unequal to zero, the function is public and might be used to construct a bitmap by other 3rd-party-crates using vm-memory.

#[allow(clippy::len_without_is_empty)]
impl AtomicBitmap {
    /// Create a new bitmap of `byte_size`, with one bit per page. This is effectively
    /// rounded up, and we get a new vector of the next multiple of 64 bigger than `bit_size`.
    pub fn new(byte_size: usize, page_size: usize) -> Self {
        let mut num_pages = byte_size / page_size;
        if byte_size % page_size > 0 {
            num_pages += 1;
        }

        // Adding one entry element more just in case `num_pages` is not a multiple of `64`.
        let map_size = num_pages / 64 + 1;
        let map: Vec<AtomicU64> = (0..map_size).map(|_| AtomicU64::new(0)).collect();

        AtomicBitmap {
            map,
            size: num_pages,
            page_size,
        }
    }
    // [...]
}

X41 advises performing thorough input parameter validation to prevent any possibility of encountering a Divide-by-zero situation.