]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix hang on fork
authorSamuel Thibault <samuel.thibault@ens-lyon.org>
Thu, 28 Aug 2014 20:08:39 +0000 (22:08 +0200)
committerSamuel Thibault <samuel.thibault@ens-lyon.org>
Thu, 28 Aug 2014 20:09:29 +0000 (22:09 +0200)
If e.g. a signal is being received while we are running fork(), the signal
thread may be having our SS lock when we make the space copy, and thus in the
child we can not take the SS lock any more.

* sysdeps/mach/hurd/fork.c (__fork): Lock SS->lock around __proc_dostop call.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
ChangeLog
sysdeps/mach/hurd/fork.c

index 23c900dcf7bb0e7893f773ede878ae34a852cd23..eb604b854b61fd438990f42baef8c79f60987625 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-28  Samuel Thibault  <samuel.thibault@ens-lyon.org>
+
+       * sysdeps/mach/hurd/fork.c (__fork): Lock SS->lock around
+       __proc_dostop call.
+
 2014-08-27  Mark Wielaard  <mjw@redhat.com>
 
        [BZ #17319]
index 60c34c762065723bddfd28ba627d995e418c4bdb..51bc2c075317b583ad64aedffb5824bf4a08c5f6 100644 (file)
@@ -129,9 +129,13 @@ __fork (void)
       ports_locked = 1;
 
 
+      /* Keep our SS locked while stopping other threads, so they don't get a
+         chance to have it locked in the copied space.  */
+      __spin_lock (&ss->lock);
       /* Stop all other threads while copying the address space,
         so nothing changes.  */
       err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
+      __spin_unlock (&ss->lock);
       if (!err)
        {
          stopped = 1;