Hi everyone, I’m trying to analyze device drivers in Rust.
I noticed many drivers in redox-os/drivers seem to trust the input from Dma/Mmio/Pio. I assumed that inputs from these sources could be malicious (i.e. tainted in static analysis terminology). Thus these inputs should be validated before being used at critical places like array indices or loop conditions, otherwise they can cause a kernel panic due to OOB or an infinite loop in kernel.
For example in e1000d
the code (e1000d/src/device.rs · master · redox-os / drivers · GitLab)
// impl SchemeBlockMut for Intel8254x -> fn read
let desc = unsafe { &mut *(self.receive_ring.as_ptr().add(self.receive_index) as *mut Rd) };
if desc.status & RD_DD == RD_DD {
desc.status = 0;
let data = &self.receive_buffer[self.receive_index][..desc.length as usize];
desc
is read from DMA and desc.length
is used as a slice index. If desc.length
is larger than 16384 this would result in a kernel panic. A trivial fix is using min(desc.length, 16384)
.
I also noticed a couple of similar patterns in drivers ac97d, ixgbed, nvmed, rtl8168d.
Can we confirm this is kind of a bug? Thank you very much!