From 8e31cafb268938729a1314806a924d73fb1991c5 Mon Sep 17 00:00:00 2001 From: Torvald Riegel Date: Wed, 21 Dec 2016 13:37:19 +0100 Subject: [PATCH] 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. --- ChangeLog | 6 ++++++ sysdeps/nptl/fork.c | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf7b236..b4defdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2016-01-13 Torvald Riegel + [BZ #19402] + * sysdeps/nptl/fork.c (__libc_fork): Clear list of acquired robust + mutexes. + +2016-01-13 Torvald Riegel + [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 72fa82a..db6d721 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)); -- 2.7.4