mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 21:55:20 +00:00
vhost-user-fs: validate fs_slave_map/unmap/sync request
In fs_slave_map/unmap/sync, we only made sure offset < cache_size, but didn't validate (offset + len). We should ensure [offset, offset+len] is within cache range as well. Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
This commit is contained in:
parent
0c29c2ec49
commit
78b5cbc63a
@ -40,6 +40,18 @@ struct SlaveReqHandler {
|
||||
mmap_cache_addr: u64,
|
||||
}
|
||||
|
||||
impl SlaveReqHandler {
|
||||
// Make sure request is within cache range
|
||||
fn is_req_valid(&self, offset: u64, len: u64) -> bool {
|
||||
let end = match offset.checked_add(len) {
|
||||
Some(n) => n,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
!(offset >= self.cache_size || end > self.cache_size)
|
||||
}
|
||||
}
|
||||
|
||||
impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
fn handle_config_change(&mut self) -> HandlerResult<u64> {
|
||||
debug!("handle_config_change");
|
||||
@ -50,20 +62,23 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
debug!("fs_slave_map");
|
||||
|
||||
for i in 0..VHOST_USER_FS_SLAVE_ENTRIES {
|
||||
let offset = fs.cache_offset[i];
|
||||
let len = fs.len[i];
|
||||
|
||||
// Ignore if the length is 0.
|
||||
if fs.len[i] == 0 {
|
||||
if len == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if fs.cache_offset[i] > self.cache_size {
|
||||
if !self.is_req_valid(offset, len) {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Wrong offset"));
|
||||
}
|
||||
|
||||
let addr = self.mmap_cache_addr + fs.cache_offset[i];
|
||||
let addr = self.mmap_cache_addr + offset;
|
||||
let ret = unsafe {
|
||||
libc::mmap(
|
||||
addr as *mut libc::c_void,
|
||||
fs.len[i] as usize,
|
||||
len as usize,
|
||||
fs.flags[i].bits() as i32,
|
||||
libc::MAP_SHARED | libc::MAP_FIXED,
|
||||
fd,
|
||||
@ -87,6 +102,7 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
debug!("fs_slave_unmap");
|
||||
|
||||
for i in 0..VHOST_USER_FS_SLAVE_ENTRIES {
|
||||
let offset = fs.cache_offset[i];
|
||||
let mut len = fs.len[i];
|
||||
|
||||
// Ignore if the length is 0.
|
||||
@ -100,11 +116,11 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
len = self.cache_size;
|
||||
}
|
||||
|
||||
if fs.cache_offset[i] > self.cache_size {
|
||||
if !self.is_req_valid(offset, len) {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Wrong offset"));
|
||||
}
|
||||
|
||||
let addr = self.mmap_cache_addr + fs.cache_offset[i];
|
||||
let addr = self.mmap_cache_addr + offset;
|
||||
let ret = unsafe {
|
||||
libc::mmap(
|
||||
addr as *mut libc::c_void,
|
||||
@ -127,19 +143,21 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
debug!("fs_slave_sync");
|
||||
|
||||
for i in 0..VHOST_USER_FS_SLAVE_ENTRIES {
|
||||
let offset = fs.cache_offset[i];
|
||||
let len = fs.len[i];
|
||||
|
||||
// Ignore if the length is 0.
|
||||
if fs.len[i] == 0 {
|
||||
if len == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if fs.cache_offset[i] > self.cache_size {
|
||||
if !self.is_req_valid(offset, len) {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Wrong offset"));
|
||||
}
|
||||
|
||||
let addr = self.mmap_cache_addr + fs.cache_offset[i];
|
||||
let ret = unsafe {
|
||||
libc::msync(addr as *mut libc::c_void, fs.len[i] as usize, libc::MS_SYNC)
|
||||
};
|
||||
let addr = self.mmap_cache_addr + offset;
|
||||
let ret =
|
||||
unsafe { libc::msync(addr as *mut libc::c_void, len as usize, libc::MS_SYNC) };
|
||||
if ret == -1 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user