mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 21:55:20 +00:00
virtio-fs: validate request len in fs_slave_io()
We made sure gpa is in cache range, but not the end addr of request, which is (gpa + len). If the end addr of request is beyond dax cache window, vmm would corrupt guest memory or crash. Fix it by making sure end addr of request is within cache range as well. And while we're at it, return EFAULT if the request is out of range, as write(2)/read(2) returns EFAULT when buffer is outside accessible address space. Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
This commit is contained in:
parent
4c9d15d44c
commit
61e34331c2
@ -161,20 +161,21 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
let mut foffset = fs.fd_offset[i];
|
||||
let mut len = fs.len[i] as usize;
|
||||
let gpa = fs.cache_offset[i];
|
||||
if gpa < self.cache_offset.raw_value()
|
||||
|| gpa >= self.cache_offset.raw_value() + self.cache_size
|
||||
{
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"gpa is out of cache range",
|
||||
));
|
||||
}
|
||||
let cache_end = self.cache_offset.raw_value() + self.cache_size;
|
||||
let efault = libc::EFAULT;
|
||||
|
||||
let offset = gpa
|
||||
.checked_sub(self.cache_offset.raw_value())
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "gpa is out of cache range"))?;
|
||||
let mut ptr = self.mmap_cache_addr + offset;
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
||||
let end = gpa
|
||||
.checked_add(fs.len[i])
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
||||
|
||||
if gpa < self.cache_offset.raw_value() || gpa >= cache_end || end >= cache_end {
|
||||
return Err(io::Error::from_raw_os_error(efault));
|
||||
}
|
||||
|
||||
let mut ptr = self.mmap_cache_addr + offset;
|
||||
while len > 0 {
|
||||
let ret = if (fs.flags[i] & VhostUserFSSlaveMsgFlags::MAP_W)
|
||||
== VhostUserFSSlaveMsgFlags::MAP_W
|
||||
|
Loading…
Reference in New Issue
Block a user