about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTorvald Riegel <triegel@redhat.com>2016-12-21 13:37:19 +0100
committerTorvald Riegel <triegel@redhat.com>2017-01-13 17:17:38 +0100
commit8e31cafb268938729a1314806a924d73fb1991c5 (patch)
treed58fa0d10a2a6eff2e8f3a5a775fa4fa1abdf271
parent65810f0ef05e8c9e333f17a44e77808b163ca298 (diff)
downloadglibc-8e31cafb268938729a1314806a924d73fb1991c5.tar.gz
glibc-8e31cafb268938729a1314806a924d73fb1991c5.tar.xz
glibc-8e31cafb268938729a1314806a924d73fb1991c5.zip
Clear list of acquired robust mutexes in the child process after forking.
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.
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/nptl/fork.c20
2 files changed, 20 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index bf7b236b48..b4defdbda2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 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]
 	* nptl/Makefile: Adapt.
 	* nptl/pthread_mutex_cond_lock.c (LLL_ROBUST_MUTEX_LOCK): Remove.
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
index 72fa82a47b..db6d721fce 100644
--- a/sysdeps/nptl/fork.c
+++ b/sysdeps/nptl/fork.c
@@ -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));