diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index 2da33bd2a5e698a17cb76185e948a889d7ddc8a7..161896d515b6486aafd43e10c27546470b2bab0d 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -1316,30 +1316,39 @@ pub fn mprotect(address: usize, size: usize, flags: MapFlags) -> Result<usize> {
     let start_page = Page::containing_address(VirtualAddress::new(address));
     let end_page = Page::containing_address(VirtualAddress::new(end_address));
     for page in Page::range_inclusive(start_page, end_page) {
-        if let Some(mut page_flags) = active_table.translate_page_flags(page) {
-            if flags.contains(PROT_EXEC) {
-                page_flags.remove(EntryFlags::NO_EXECUTE);
-            } else {
-                page_flags.insert(EntryFlags::NO_EXECUTE);
-            }
+        // Check if the page is actually mapped before trying to change the flags.
+        // FIXME can other processes change if a page is mapped beneath our feet?
+        let mut page_flags = if let Some(page_flags) = active_table.translate_page_flags(page) {
+            page_flags
+        } else {
+            flush_all.flush(&mut active_table);
+            return Err(Error::new(EFAULT));
+        };
+        if !page_flags.contains(EntryFlags::PRESENT) {
+            flush_all.flush(&mut active_table);
+            return Err(Error::new(EFAULT));
+        }
 
-            if flags.contains(PROT_WRITE) {
-                //TODO: Not allowing gain of write privileges
-            } else {
-                page_flags.remove(EntryFlags::WRITABLE);
-            }
+        if flags.contains(PROT_EXEC) {
+            page_flags.remove(EntryFlags::NO_EXECUTE);
+        } else {
+            page_flags.insert(EntryFlags::NO_EXECUTE);
+        }
 
-            if flags.contains(PROT_READ) {
-                //TODO: No flags for readable pages
-            } else {
-                //TODO: No flags for readable pages
-            }
+        if flags.contains(PROT_WRITE) {
+            //TODO: Not allowing gain of write privileges
+        } else {
+            page_flags.remove(EntryFlags::WRITABLE);
+        }
 
-            let flush = active_table.remap(page, page_flags);
-            flush_all.consume(flush);
+        if flags.contains(PROT_READ) {
+            //TODO: No flags for readable pages
         } else {
-            return Err(Error::new(EFAULT));
+            //TODO: No flags for readable pages
         }
+
+        let flush = active_table.remap(page, page_flags);
+        flush_all.consume(flush);
     }
 
     flush_all.flush(&mut active_table);