Fix integer overflow caused by large addr + size in memory related syscall

This commit is contained in:
Marsman1996
2024-08-26 13:54:11 +08:00
committed by Tate, Hongliang Tian
parent e6e771e9b5
commit 0a8ad6971a
4 changed files with 25 additions and 7 deletions

View File

@ -25,6 +25,10 @@ pub fn sys_madvise(
} }
let len = len.align_up(PAGE_SIZE); let len = len.align_up(PAGE_SIZE);
let end = start.checked_add(len).ok_or(Error::with_message(
Errno::EINVAL,
"integer overflow when (start + len)",
))?;
match behavior { match behavior {
MadviseBehavior::MADV_NORMAL MadviseBehavior::MADV_NORMAL
| MadviseBehavior::MADV_SEQUENTIAL | MadviseBehavior::MADV_SEQUENTIAL
@ -37,15 +41,15 @@ pub fn sys_madvise(
MadviseBehavior::MADV_DONTNEED => { MadviseBehavior::MADV_DONTNEED => {
warn!("MADV_DONTNEED isn't implemented, do nothing for now."); warn!("MADV_DONTNEED isn't implemented, do nothing for now.");
} }
MadviseBehavior::MADV_FREE => madv_free(start, len, ctx)?, MadviseBehavior::MADV_FREE => madv_free(start, end, ctx)?,
_ => todo!(), _ => todo!(),
} }
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }
fn madv_free(start: Vaddr, len: usize, ctx: &Context) -> Result<()> { fn madv_free(start: Vaddr, end: Vaddr, ctx: &Context) -> Result<()> {
let root_vmar = ctx.process.root_vmar(); let root_vmar = ctx.process.root_vmar();
let advised_range = start..start + len; let advised_range = start..end;
let _ = root_vmar.destroy(advised_range); let _ = root_vmar.destroy(advised_range);
Ok(()) Ok(())

View File

@ -24,7 +24,11 @@ pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, ctx: &Context) -> Resul
} }
let len = len.align_up(PAGE_SIZE); let len = len.align_up(PAGE_SIZE);
let range = addr..(addr + len); let end = addr.checked_add(len).ok_or(Error::with_message(
Errno::ENOMEM,
"integer overflow when (addr + len)",
))?;
let range = addr..end;
root_vmar.protect(vm_perms, range)?; root_vmar.protect(vm_perms, range)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -17,7 +17,11 @@ pub fn sys_munmap(addr: Vaddr, len: usize, ctx: &Context) -> Result<SyscallRetur
let root_vmar = ctx.process.root_vmar(); let root_vmar = ctx.process.root_vmar();
let len = len.align_up(PAGE_SIZE); let len = len.align_up(PAGE_SIZE);
debug!("unmap range = 0x{:x} - 0x{:x}", addr, addr + len); let end = addr.checked_add(len).ok_or(Error::with_message(
root_vmar.destroy(addr..addr + len)?; Errno::EINVAL,
"integer overflow when (addr + len)",
))?;
debug!("unmap range = 0x{:x} - 0x{:x}", addr, end);
root_vmar.destroy(addr..end)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -164,7 +164,13 @@ impl VmarInner {
let region_start = free_region.start(); let region_start = free_region.start();
let region_end = free_region.end(); let region_end = free_region.end();
let child_vmar_real_start = region_start.align_up(align); let child_vmar_real_start = region_start.align_up(align);
let child_vmar_real_end = child_vmar_real_start + child_size; let child_vmar_real_end =
child_vmar_real_start
.checked_add(child_size)
.ok_or(Error::with_message(
Errno::ENOMEM,
"integer overflow whem (child_vmar_real_start + child_size)",
))?;
if region_start <= child_vmar_real_start && child_vmar_real_end <= region_end { if region_start <= child_vmar_real_start && child_vmar_real_end <= region_end {
return Ok((*region_base, child_vmar_real_start)); return Ok((*region_base, child_vmar_real_start));
} }