]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Clear list of acquired robust mutexes in the child process after forking.
authorTorvald Riegel <triegel@redhat.com>
Wed, 21 Dec 2016 12:37:19 +0000 (13:37 +0100)
committerTorvald Riegel <triegel@redhat.com>
Fri, 13 Jan 2017 16:17:38 +0000 (17:17 +0100)
Robust mutexes acquired at the time of a call to fork() do not remain
acquired by the forked child process.  We have to clear the list of
acquired robust mutexes before registering this list with the kernel;
otherwise, if some of the robust mutexes are process-shared, the parent
process can alter the child's robust mutex list, which can lead to
deadlocks or even modification of memory that may not be occupied by a
mutex anymore.

[BZ #19402]
* sysdeps/nptl/fork.c (__libc_fork): Clear list of acquired robust
mutexes.

ChangeLog
sysdeps/nptl/fork.c

index bf7b236b481eb0a4326791ccd0464c66f5c27502..b4defdbda2e59c9559f7e33e2308150fef72dd8d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-01-13  Torvald Riegel  <triegel@redhat.com>
+
+       [BZ #19402]
+       * sysdeps/nptl/fork.c (__libc_fork): Clear list of acquired robust
+       mutexes.
+
 2016-01-13  Torvald Riegel  <triegel@redhat.com>
 
        [BZ #20985]
index 72fa82a47b9edff3d39162fca50d7abd5f20cae0..db6d721fce9c61446315683389d11619bb60f737 100644 (file)
@@ -162,12 +162,20 @@ __libc_fork (void)
 #endif
 
 #ifdef __NR_set_robust_list
-      /* Initialize the robust mutex list which has been reset during
-        the fork.  We do not check for errors since if it fails here
-        it failed at process start as well and noone could have used
-        robust mutexes.  We also do not have to set
-        self->robust_head.futex_offset since we inherit the correct
-        value from the parent.  */
+      /* Initialize the robust mutex list setting in the kernel which has
+        been reset during the fork.  We do not check for errors because if
+        it fails here, it must have failed at process startup as well and
+        nobody could have used robust mutexes.
+        Before we do that, we have to clear the list of robust mutexes
+        because we do not inherit ownership of mutexes from the parent.
+        We do not have to set self->robust_head.futex_offset since we do
+        inherit the correct value from the parent.  We do not need to clear
+        the pending operation because it must have been zero when fork was
+        called.  */
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
+      self->robust_prev = &self->robust_head;
+# endif
+      self->robust_head.list = &self->robust_head;
 # ifdef SHARED
       if (__builtin_expect (__libc_pthread_functions_init, 0))
        PTHFCT_CALL (ptr_set_robust, (self));