summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Soller <jackpot51@gmail.com>2016-12-13 20:42:25 -0700
committerGitHub <noreply@github.com>2016-12-13 20:42:25 -0700
commit0b04c9e3b4e0d77195fd979813e068f6bd3f6e34 (patch)
treea2ae5c9b8b5c3f5a96eed7ef1eab7275ba0eca55
parent041dc7eaf4f5fe1bc238fc8c47a1a4223f2b595e (diff)
parent4586dbc6063985bcad6235b2b8392f4ff40ccea4 (diff)
Merge pull request #783 from redox-os/fix_virtualbox_issues0.0.5
Fix Virtualbox failures
-rw-r--r--kernel/common/mod.rs1
-rw-r--r--kernel/lib.rs2
-rw-r--r--kernel/syscall/process.rs81
3 files changed, 46 insertions, 38 deletions
diff --git a/kernel/common/mod.rs b/kernel/common/mod.rs
index 62c5921..29f6412 100644
--- a/kernel/common/mod.rs
+++ b/kernel/common/mod.rs
@@ -1,3 +1,2 @@
#[macro_use]
-#[macro_export]
pub mod int_like;
diff --git a/kernel/lib.rs b/kernel/lib.rs
index 8a1a8b1..ecb34b1 100644
--- a/kernel/lib.rs
+++ b/kernel/lib.rs
@@ -3,6 +3,7 @@
//! The Redox OS Kernel is a hybrid kernel that supports X86_64 systems and
//! provides Unix-like syscalls for primarily Rust applications
+#![deny(warnings)]
#![feature(alloc)]
#![feature(arc_counts)]
#![feature(asm)]
@@ -46,7 +47,6 @@ use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use scheme::FileHandle;
#[macro_use]
-#[macro_export]
/// Shared data structures
pub mod common;
diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs
index d784acf..cde11be 100644
--- a/kernel/syscall/process.rs
+++ b/kernel/syscall/process.rs
@@ -450,6 +450,41 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
Ok(pid)
}
+fn empty(context: &mut context::Context, reaping: bool) {
+ if reaping {
+ // Memory should already be unmapped
+ assert!(context.image.is_empty());
+ assert!(context.heap.is_none());
+ assert!(context.stack.is_none());
+ assert!(context.tls.is_none());
+ } else {
+ // Unmap previous image, heap, grants, stack, and tls
+ context.image.clear();
+ drop(context.heap.take());
+ drop(context.stack.take());
+ drop(context.tls.take());
+ }
+
+ // FIXME: Looks like a race condition.
+ // Is it possible for Arc::strong_count to return 1 to two contexts that exit at the
+ // same time, or return 2 to both, thus either double freeing or leaking the grants?
+ if Arc::strong_count(&context.grants) == 1 {
+ let mut grants = context.grants.lock();
+ for grant in grants.drain(..) {
+ if reaping {
+ println!("{}: {}: Grant should not exist: {:?}", context.id.into(), unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, grant);
+
+ let mut new_table = unsafe { InactivePageTable::from_address(context.arch.get_page_table()) };
+ let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(arch::USER_TMP_GRANT_OFFSET)));
+
+ grant.unmap_inactive(&mut new_table, &mut temporary_page);
+ } else {
+ grant.unmap();
+ }
+ }
+ }
+}
+
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
let entry;
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
@@ -508,24 +543,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
// Set name
context.name = Arc::new(Mutex::new(canonical));
- // Unmap previous image, heap, grants, stack, and tls
- context.image.clear();
- drop(context.heap.take());
- drop(context.stack.take());
- drop(context.tls.take());
-
- let mut unmap_grants = Vec::new();
- // FIXME: Looks like a race condition.
- // Is it possible for Arc::strong_count to return 1 to two contexts that exit at the
- // same time, or return 2 to both, thus either double freeing or leaking the grants?
- if Arc::strong_count(&context.grants) == 1 {
- mem::swap(context.grants.lock().deref_mut(), &mut unmap_grants);
- }
- context.grants = Arc::new(Mutex::new(Vec::new()));
-
- for grant in unmap_grants {
- grant.unmap();
- }
+ empty(&mut context, false);
if stat.st_mode & syscall::flag::MODE_SETUID == syscall::flag::MODE_SETUID {
context.euid = stat.st_uid;
@@ -807,23 +825,7 @@ pub fn exit(status: usize) -> ! {
let (vfork, children) = {
let mut context = context_lock.write();
- context.image.clear();
- drop(context.heap.take());
- drop(context.stack.take());
- drop(context.tls.take());
-
- let mut unmap_grants = Vec::new();
- // FIXME: Looks like a race condition.
- // Is it possible for Arc::strong_count to return 1 to two contexts that exit at the
- // same time, or return 2 to both, thus either double freeing or leaking the grants?
- if Arc::strong_count(&context.grants) == 1 {
- mem::swap(context.grants.lock().deref_mut(), &mut unmap_grants);
- }
- context.grants = Arc::new(Mutex::new(Vec::new()));
-
- for grant in unmap_grants {
- grant.unmap();
- }
+ empty(&mut context, false);
let vfork = context.vfork;
context.vfork = false;
@@ -911,7 +913,14 @@ fn reap(pid: ContextId) -> Result<ContextId> {
}
let mut contexts = context::contexts_mut();
- contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid))
+ let context_lock = contexts.remove(pid).ok_or(Error::new(ESRCH))?;
+ {
+ let mut context = context_lock.write();
+ empty(&mut context, true);
+ }
+ drop(context_lock);
+
+ Ok(pid)
}
pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<ContextId> {