diff --git a/kernel/src/syscall/mmap.rs b/kernel/src/syscall/mmap.rs index 948014f9b..93bc277ab 100644 --- a/kernel/src/syscall/mmap.rs +++ b/kernel/src/syscall/mmap.rs @@ -74,6 +74,15 @@ fn do_sys_mmap( return_errno_with_message!(Errno::ENOMEM, "mmap (addr + len) too large"); } + // On x86, `PROT_WRITE` implies `PROT_READ`. + // + #[cfg(target_arch = "x86_64")] + let vm_perms = if !vm_perms.contains(VmPerms::READ) && vm_perms.contains(VmPerms::WRITE) { + vm_perms | VmPerms::READ + } else { + vm_perms + }; + let root_vmar = ctx.process.root_vmar(); let vm_map_options = { let mut options = root_vmar.new_map(len, vm_perms)?; diff --git a/kernel/src/syscall/mprotect.rs b/kernel/src/syscall/mprotect.rs index 62fd7c8c5..f55c5f8dc 100644 --- a/kernel/src/syscall/mprotect.rs +++ b/kernel/src/syscall/mprotect.rs @@ -32,6 +32,16 @@ pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, ctx: &Context) -> Resul "integer overflow when (addr + len)", ))?; let range = addr..end; + + // On x86, `PROT_WRITE` implies `PROT_READ`. + // + #[cfg(target_arch = "x86_64")] + let vm_perms = if !vm_perms.contains(VmPerms::READ) && vm_perms.contains(VmPerms::WRITE) { + vm_perms | VmPerms::READ + } else { + vm_perms + }; + root_vmar.protect(vm_perms, range)?; Ok(SyscallReturn::Return(0)) }