diff --git a/src/platform/redox/clone.rs b/src/platform/redox/clone.rs
index 4bb4da8efdf46bcb37c67ae0ced58705b2f6a1a0..336c0937cf7e2eedb60790373ccad1f482132b70 100644
--- a/src/platform/redox/clone.rs
+++ b/src/platform/redox/clone.rs
@@ -7,6 +7,8 @@ use syscall::{
     SetSighandlerData, SIGCONT,
 };
 
+use crate::sync::rwlock::Rwlock;
+
 use super::{
     extra::{create_set_addr_space_buf, FdGuard},
     signal::sighandler_function,
@@ -14,6 +16,26 @@ use super::{
 
 pub use redox_exec::*;
 
+static CLONE_LOCK: Rwlock = Rwlock::new(crate::pthread::Pshared::Private);
+
+struct Guard;
+impl Drop for Guard {
+    fn drop(&mut self) {
+        CLONE_LOCK.unlock()
+    }
+}
+
+pub fn rdlock() -> impl Drop {
+    CLONE_LOCK.acquire_read_lock(None);
+
+    Guard
+}
+pub fn wrlock() -> impl Drop {
+    CLONE_LOCK.acquire_write_lock(None);
+
+    Guard
+}
+
 /// Spawns a new context sharing the same address space as the current one (i.e. a new thread).
 pub unsafe fn rlct_clone_impl(stack: *mut usize) -> Result<usize> {
     let cur_pid_fd = FdGuard::new(syscall::open("thisproc:current/open_via_dup", O_CLOEXEC)?);
diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
index 8023077afe1f39764ed4512f0ad38f860ab99752..36c844bc8eb6a7b54391e0f6a912e27fc57d7458 100644
--- a/src/platform/redox/mod.rs
+++ b/src/platform/redox/mod.rs
@@ -277,7 +277,9 @@ impl Pal for Sys {
     }
 
     fn fork() -> pid_t {
-        e(clone::fork_impl()) as pid_t
+        let _guard = clone::wrlock();
+        let res = clone::fork_impl();
+        e(res) as pid_t
     }
 
     // FIXME: unsound
@@ -789,8 +791,10 @@ impl Pal for Sys {
     unsafe fn rlct_clone(
         stack: *mut usize,
     ) -> Result<crate::pthread::OsTid, crate::pthread::Errno> {
-        clone::rlct_clone_impl(stack)
-            .map(|context_id| crate::pthread::OsTid { context_id })
+        let _guard = clone::rdlock();
+        let res = clone::rlct_clone_impl(stack);
+
+        res.map(|context_id| crate::pthread::OsTid { context_id })
             .map_err(|error| crate::pthread::Errno(error.errno))
     }
     unsafe fn rlct_kill(
diff --git a/src/sync/rwlock.rs b/src/sync/rwlock.rs
index 30aae21c01d0813bfb72c193f00c496009c87d34..fe066a1798c57a18c2e09f238e202a2f153f572d 100644
--- a/src/sync/rwlock.rs
+++ b/src/sync/rwlock.rs
@@ -16,7 +16,7 @@ const EXCLUSIVE: u32 = COUNT_MASK;
 // TODO: Add futex ops that use bitmasks.
 
 impl Rwlock {
-    pub fn new(_pshared: Pshared) -> Self {
+    pub const fn new(_pshared: Pshared) -> Self {
         Self {
             state: AtomicU32::new(0),
         }