c6d234
commit 8e31cafb268938729a1314806a924d73fb1991c5
c6d234
Author: Torvald Riegel <triegel@redhat.com>
c6d234
Date:   Wed Dec 21 13:37:19 2016 +0100
c6d234
c6d234
    Clear list of acquired robust mutexes in the child process after forking.
c6d234
    
c6d234
    Robust mutexes acquired at the time of a call to fork() do not remain
c6d234
    acquired by the forked child process.  We have to clear the list of
c6d234
    acquired robust mutexes before registering this list with the kernel;
c6d234
    otherwise, if some of the robust mutexes are process-shared, the parent
c6d234
    process can alter the child's robust mutex list, which can lead to
c6d234
    deadlocks or even modification of memory that may not be occupied by a
c6d234
    mutex anymore.
c6d234
    
c6d234
            [BZ #19402]
c6d234
            * sysdeps/nptl/fork.c (__libc_fork): Clear list of acquired robust
c6d234
            mutexes.
c6d234
c6d234
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/fork.c
c6d234
===================================================================
c6d234
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/fork.c
c6d234
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/fork.c
c6d234
@@ -161,12 +161,20 @@ __libc_fork (void)
c6d234
 #endif
c6d234
 
c6d234
 #ifdef __NR_set_robust_list
c6d234
-      /* Initialize the robust mutex list which has been reset during
c6d234
-	 the fork.  We do not check for errors since if it fails here
c6d234
-	 it failed at process start as well and noone could have used
c6d234
-	 robust mutexes.  We also do not have to set
c6d234
-	 self->robust_head.futex_offset since we inherit the correct
c6d234
-	 value from the parent.  */
c6d234
+      /* Initialize the robust mutex list setting in the kernel which has
c6d234
+	 been reset during the fork.  We do not check for errors because if
c6d234
+	 it fails here, it must have failed at process startup as well and
c6d234
+	 nobody could have used robust mutexes.
c6d234
+	 Before we do that, we have to clear the list of robust mutexes
c6d234
+	 because we do not inherit ownership of mutexes from the parent.
c6d234
+	 We do not have to set self->robust_head.futex_offset since we do
c6d234
+	 inherit the correct value from the parent.  We do not need to clear
c6d234
+	 the pending operation because it must have been zero when fork was
c6d234
+	 called.  */
c6d234
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
c6d234
+      self->robust_prev = &self->robust_head;
c6d234
+# endif
c6d234
+      self->robust_head.list = &self->robust_head;
c6d234
 # ifdef SHARED
c6d234
       if (__builtin_expect (__libc_pthread_functions_init, 0))
c6d234
 	PTHFCT_CALL (ptr_set_robust, (self));