diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs
index 9b7dbfc385739894d9d2e238de74fcaff9eab3c0..218bf18da37f84cc20cc2296d8c86cac5e6617d3 100644
--- a/redox-rt/src/proc.rs
+++ b/redox-rt/src/proc.rs
@@ -713,12 +713,6 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
         let cur_pid_fd = FdGuard::new(syscall::open("thisproc:current/open_via_dup", O_CLOEXEC)?);
         (new_pid_fd, new_pid) = new_context()?;
 
-        // Reuse the same sigaltstack and signal entry (all memory will be re-mapped CoW later).
-        {
-            let new_sighandler_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"sighandler")?);
-            let _ = syscall::write(*new_sighandler_fd, &crate::signal::current_setsighandler_struct())?;
-        }
-
         copy_str(*cur_pid_fd, *new_pid_fd, "name")?;
 
         // Copy existing files into new file table, but do not reuse the same file table (i.e. new
@@ -801,6 +795,15 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
                 }
             }
 
+            // Reuse the same sigaltstack and signal entry (all memory will be re-mapped CoW later).
+            //
+            // Do this after the address space is cloned, since the kernel will get a shared
+            // reference to the TCB and whatever pages stores the signal proc control struct.
+            {
+                let new_sighandler_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"sighandler")?);
+                let _ = syscall::write(*new_sighandler_fd, &crate::signal::current_setsighandler_struct())?;
+            }
+
             let buf = create_set_addr_space_buf(
                 *new_addr_space_fd,
                 __relibc_internal_fork_ret as usize,