diff --git a/kernel/src/syscall/mmap.rs b/kernel/src/syscall/mmap.rs index 35536068b..5d5ad9955 100644 --- a/kernel/src/syscall/mmap.rs +++ b/kernel/src/syscall/mmap.rs @@ -56,7 +56,7 @@ fn do_sys_mmap( option.flags.insert(MMapFlags::MAP_FIXED); } - check_option(addr, &option)?; + check_option(addr, len, &option)?; if len == 0 { return_errno_with_message!(Errno::EINVAL, "mmap len cannot be zero"); @@ -153,12 +153,15 @@ fn do_sys_mmap( Ok(map_addr) } -fn check_option(addr: Vaddr, option: &MMapOptions) -> Result<()> { +fn check_option(addr: Vaddr, size: usize, option: &MMapOptions) -> Result<()> { if option.typ() == MMapType::File { return_errno_with_message!(Errno::EINVAL, "Invalid mmap type"); } - if option.flags().contains(MMapFlags::MAP_FIXED) && !is_userspace_vaddr(addr) { + let map_end = addr.checked_add(size).ok_or(Errno::EINVAL)?; + if option.flags().contains(MMapFlags::MAP_FIXED) + && !(is_userspace_vaddr(addr) && is_userspace_vaddr(map_end - 1)) + { return_errno_with_message!(Errno::EINVAL, "Invalid mmap fixed addr"); } diff --git a/kernel/src/vm/vmar/mod.rs b/kernel/src/vm/vmar/mod.rs index 687b86d82..53127999f 100644 --- a/kernel/src/vm/vmar/mod.rs +++ b/kernel/src/vm/vmar/mod.rs @@ -391,7 +391,7 @@ impl VmarInner { let old_map_end = map_addr + old_size; let new_map_end = map_addr.checked_add(new_size).ok_or(Errno::EINVAL)?; - if !is_userspace_vaddr(new_map_end) { + if !is_userspace_vaddr(new_map_end - 1) { return_errno_with_message!(Errno::EINVAL, "resize to a invalid new size"); } @@ -604,7 +604,7 @@ impl Vmar_ { let new_range = new_addr..new_addr.checked_add(new_size).ok_or(Errno::EINVAL)?; if new_addr % PAGE_SIZE != 0 || !is_userspace_vaddr(new_addr) - || !is_userspace_vaddr(new_range.end) + || !is_userspace_vaddr(new_range.end - 1) { return_errno_with_message!(Errno::EINVAL, "remap: invalid fixed new addr"); }