From b8926035018c5740a0f7ae8f99ba87ebfccb376f Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jeremy@system76.com>
Date: Mon, 10 Feb 2020 17:58:44 -0700
Subject: [PATCH] Require mutable context to perform page table modifications

---
 src/context/arch/x86_64.rs |  2 +-
 src/ptrace.rs              |  2 +-
 src/scheme/proc.rs         |  8 ++++----
 src/scheme/user.rs         | 12 ++++++------
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/context/arch/x86_64.rs b/src/context/arch/x86_64.rs
index 85d172aa..fa108a0a 100644
--- a/src/context/arch/x86_64.rs
+++ b/src/context/arch/x86_64.rs
@@ -53,7 +53,7 @@ impl Context {
         }
     }
 
-    pub fn get_page_table(&self) -> usize {
+    pub fn get_page_table(&mut self) -> usize {
         self.cr3
     }
 
diff --git a/src/ptrace.rs b/src/ptrace.rs
index b3631969..193c702e 100644
--- a/src/ptrace.rs
+++ b/src/ptrace.rs
@@ -421,7 +421,7 @@ pub unsafe fn regs_for_mut(context: &mut Context) -> Option<&mut InterruptStack>
 // |_|  |_|\___|_| |_| |_|\___/|_|   \__, |
 //                                   |___/
 
-pub fn with_context_memory<F>(context: &Context, offset: VirtualAddress, len: usize, f: F) -> Result<()>
+pub fn with_context_memory<F>(context: &mut Context, offset: VirtualAddress, len: usize, f: F) -> Result<()>
     where F: FnOnce(*mut u8) -> Result<()>
 {
     // As far as I understand, mapping any regions following
diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs
index 9eaf0d4a..31672bc0 100644
--- a/src/scheme/proc.rs
+++ b/src/scheme/proc.rs
@@ -321,9 +321,9 @@ impl Scheme for ProcScheme {
 
                 let contexts = context::contexts();
                 let context = contexts.get(info.pid).ok_or(Error::new(ESRCH))?;
-                let context = context.read();
+                let mut context = context.write();
 
-                ptrace::with_context_memory(&context, data.offset, buf.len(), |ptr| {
+                ptrace::with_context_memory(&mut context, data.offset, buf.len(), |ptr| {
                     buf.copy_from_slice(validate::validate_slice(ptr, buf.len())?);
                     Ok(())
                 })?;
@@ -411,9 +411,9 @@ impl Scheme for ProcScheme {
 
                 let contexts = context::contexts();
                 let context = contexts.get(info.pid).ok_or(Error::new(ESRCH))?;
-                let context = context.read();
+                let mut context = context.write();
 
-                ptrace::with_context_memory(&context, data.offset, buf.len(), |ptr| {
+                ptrace::with_context_memory(&mut context, data.offset, buf.len(), |ptr| {
                     validate::validate_slice_mut(ptr, buf.len())?.copy_from_slice(buf);
                     Ok(())
                 })?;
diff --git a/src/scheme/user.rs b/src/scheme/user.rs
index afcb48b3..32766d91 100644
--- a/src/scheme/user.rs
+++ b/src/scheme/user.rs
@@ -114,13 +114,13 @@ impl UserInner {
             Ok(0)
         } else {
             let context_lock = context_weak.upgrade().ok_or(Error::new(ESRCH))?;
-            let context = context_lock.read();
-
-            let mut grants = context.grants.lock();
+            let mut context = context_lock.write();
 
             let mut new_table = unsafe { InactivePageTable::from_address(context.arch.get_page_table()) };
             let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_GRANT_OFFSET)));
 
+            let mut grants = context.grants.lock();
+
             let from_address = (address/4096) * 4096;
             let offset = address - from_address;
             let full_size = ((offset + size + 4095)/4096) * 4096;
@@ -170,13 +170,13 @@ impl UserInner {
             Ok(())
         } else {
             let context_lock = self.context.upgrade().ok_or(Error::new(ESRCH))?;
-            let context = context_lock.read();
-
-            let mut grants = context.grants.lock();
+            let mut context = context_lock.write();
 
             let mut new_table = unsafe { InactivePageTable::from_address(context.arch.get_page_table()) };
             let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_GRANT_OFFSET)));
 
+            let mut grants = context.grants.lock();
+
             for i in 0 .. grants.len() {
                 let start = grants[i].start_address().get();
                 let end = start + grants[i].size();
-- 
GitLab