diff --git a/kernel/src/syscall/mmap.rs b/kernel/src/syscall/mmap.rs index 04e4ba2f6..e963c1be3 100644 --- a/kernel/src/syscall/mmap.rs +++ b/kernel/src/syscall/mmap.rs @@ -22,7 +22,7 @@ pub fn sys_mmap( offset: u64, ctx: &Context, ) -> Result { - let perms = VmPerms::from_bits_truncate(perms as u32); + let perms = VmPerms::from_user_bits_truncate(perms as u32); let option = MMapOptions::try_from(flags as u32)?; let res = do_sys_mmap( addr as usize, diff --git a/kernel/src/syscall/mprotect.rs b/kernel/src/syscall/mprotect.rs index b07be0445..7befcf9e2 100644 --- a/kernel/src/syscall/mprotect.rs +++ b/kernel/src/syscall/mprotect.rs @@ -9,7 +9,7 @@ use crate::{ }; pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, ctx: &Context) -> Result { - let vm_perms = VmPerms::from_bits_truncate(perms as u32); + let vm_perms = VmPerms::from_user_bits(perms as u32)?; debug!( "addr = 0x{:x}, len = 0x{:x}, perms = {:?}", addr, len, vm_perms diff --git a/kernel/src/vm/perms.rs b/kernel/src/vm/perms.rs index ff5884da9..79b1d6186 100644 --- a/kernel/src/vm/perms.rs +++ b/kernel/src/vm/perms.rs @@ -42,6 +42,24 @@ impl VmPerms { Ok(()) } + + /// Parses `bits` as requested permissions from user programs and returns errors + /// if there are unknown permissions. + pub fn from_user_bits(bits: u32) -> Result { + if let Some(vm_perms) = VmPerms::from_bits(bits) + && Self::ALL_PERMS.contains(vm_perms) + { + Ok(vm_perms) + } else { + return_errno_with_message!(Errno::EINVAL, "invalid permissions"); + } + } + + /// Parses `bits` as requested permissions from user programs and ignores any + /// unknown permissions. + pub fn from_user_bits_truncate(bits: u32) -> Self { + VmPerms::from_bits_truncate(bits) & Self::ALL_PERMS + } } impl From for VmPerms {