commit e67f54ab1a6253dd69cb2c770d785c7eb6d2172c
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Thu Sep 22 01:45:48 2016 +0200

    hurdmalloc: Run fork handler as late as possible [BZ #19431]
    
    This is the hurd-specific follow-up for
    29d794863cd6e03115d3670707cc873a9965ba92 : hurdmalloc also needs the
    same fix
    
            * hurd/hurdmalloc.c (malloc_fork_prepare): Rename to
            _hurd_malloc_fork_prepare.
            (malloc_fork_parent): Rename to _hurd_malloc_fork_parent.
            (malloc_fork_child): Rename to _hurd_malloc_fork_child.
            (_hurd_fork_prepare_hook): Drop malloc_fork_prepare.
            (_hurd_fork_parent_hook): Drop malloc_fork_parent.
            (_hurd_fork_child_hook): Drop malloc_fork_child.
            * hurd/hurdmalloc.h (_hurd_malloc_fork_prepare,
            _hurd_malloc_fork_parent, _hurd_malloc_fork_child): Add declarations.
            * sysdeps/mach/hurd/fork.c (__fork): Call __malloc_fork_lock_parent
            after locking locks (notably hurd_dtable_lock). Call
            _hurd_malloc_fork_prepare after that. Call _hurd_malloc_fork_parent
            before __malloc_fork_unlock_parent and _hurd_malloc_fork_child before
            __malloc_fork_unlock_child.

Index: glibc-2.24/hurd/hurdmalloc.c
===================================================================
--- glibc-2.24.orig/hurd/hurdmalloc.c
+++ glibc-2.24/hurd/hurdmalloc.c
@@ -405,8 +405,8 @@ print_malloc_free_list (void)
 }
 #endif	/* DEBUG */
 
-static void
-malloc_fork_prepare(void)
+void
+_hurd_malloc_fork_prepare(void)
 /*
  * Prepare the malloc module for a fork by insuring that no thread is in a
  * malloc critical section.
@@ -419,8 +419,8 @@ malloc_fork_prepare(void)
     }
 }
 
-static void
-malloc_fork_parent(void)
+void
+_hurd_malloc_fork_parent(void)
 /*
  * Called in the parent process after a fork() to resume normal operation.
  */
@@ -432,8 +432,8 @@ malloc_fork_parent(void)
     }
 }
 
-static void
-malloc_fork_child(void)
+void
+_hurd_malloc_fork_child(void)
 /*
  * Called in the child process after a fork() to resume normal operation.
  */
@@ -446,7 +446,4 @@ malloc_fork_child(void)
 }
 
 
-text_set_element (_hurd_fork_prepare_hook, malloc_fork_prepare);
-text_set_element (_hurd_fork_parent_hook, malloc_fork_parent);
-text_set_element (_hurd_fork_child_hook, malloc_fork_child);
 text_set_element (_hurd_preinit_hook, malloc_init);
Index: glibc-2.24/hurd/hurdmalloc.h
===================================================================
--- glibc-2.24.orig/hurd/hurdmalloc.h
+++ glibc-2.24/hurd/hurdmalloc.h
@@ -12,6 +12,10 @@ extern void *_hurd_malloc (size_t);
 extern void *_hurd_realloc (void *, size_t);
 extern void _hurd_free (void *);
 
+extern void _hurd_malloc_fork_prepare (void);
+extern void _hurd_malloc_fork_parent (void);
+extern void _hurd_malloc_fork_child (void);
+
 #define malloc	_hurd_malloc
 #define realloc	_hurd_realloc
 #define free	_hurd_free
Index: glibc-2.24/sysdeps/mach/hurd/fork.c
===================================================================
--- glibc-2.24.orig/sysdeps/mach/hurd/fork.c
+++ glibc-2.24/sysdeps/mach/hurd/fork.c
@@ -109,12 +109,6 @@ __fork (void)
       /* Run things that prepare for forking before we create the task.  */
       RUN_HOOK (_hurd_fork_prepare_hook, ());
 
-      /* Acquire malloc locks.  This needs to come last because fork
-	 handlers may use malloc, and the libio list lock has an
-	 indirect malloc dependency as well (via the getdelim
-	 function).  */
-      __malloc_fork_lock_parent ();
-
       /* Lock things that want to be locked before we fork.  */
       {
 	void *const *p;
@@ -125,6 +119,13 @@ __fork (void)
       }
       __mutex_lock (&_hurd_siglock);
 
+      /* Acquire malloc locks.  This needs to come last because fork
+	 handlers may use malloc, and the libio list lock has an
+	 indirect malloc dependency as well (via the getdelim
+	 function).  */
+      __malloc_fork_lock_parent ();
+      _hurd_malloc_fork_prepare ();
+
       newtask = MACH_PORT_NULL;
       thread = sigthread = MACH_PORT_NULL;
       newproc = MACH_PORT_NULL;
@@ -617,6 +618,7 @@ __fork (void)
 	}
 
       /* Release malloc locks.  */
+      _hurd_malloc_fork_parent ();
       __malloc_fork_unlock_parent ();
 
       /* Run things that want to run in the parent to restore it to
@@ -688,6 +690,7 @@ __fork (void)
       __sigemptyset (&ss->pending);
 
       /* Release malloc locks.  */
+      _hurd_malloc_fork_child ();
       __malloc_fork_unlock_child ();
 
       /* Run things that want to run in the child task to set up.  */
