mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +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:
committed by
Sebastien Boeuf
parent
4c9d15d44c
commit
61e34331c2
@@ -161,20 +161,21 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
|||||||
let mut foffset = fs.fd_offset[i];
|
let mut foffset = fs.fd_offset[i];
|
||||||
let mut len = fs.len[i] as usize;
|
let mut len = fs.len[i] as usize;
|
||||||
let gpa = fs.cache_offset[i];
|
let gpa = fs.cache_offset[i];
|
||||||
if gpa < self.cache_offset.raw_value()
|
let cache_end = self.cache_offset.raw_value() + self.cache_size;
|
||||||
|| gpa >= self.cache_offset.raw_value() + self.cache_size
|
let efault = libc::EFAULT;
|
||||||
{
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"gpa is out of cache range",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let offset = gpa
|
let offset = gpa
|
||||||
.checked_sub(self.cache_offset.raw_value())
|
.checked_sub(self.cache_offset.raw_value())
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "gpa is out of cache range"))?;
|
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
||||||
let mut ptr = self.mmap_cache_addr + offset;
|
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 {
|
while len > 0 {
|
||||||
let ret = if (fs.flags[i] & VhostUserFSSlaveMsgFlags::MAP_W)
|
let ret = if (fs.flags[i] & VhostUserFSSlaveMsgFlags::MAP_W)
|
||||||
== VhostUserFSSlaveMsgFlags::MAP_W
|
== VhostUserFSSlaveMsgFlags::MAP_W
|
||||||
|
|||||||
Reference in New Issue
Block a user