On Tue, Sep 04, 2012 at 05:43:28AM +0200, bugzilla@bugzilla.balabit.com wrote:
--- Comment #9 from Lennert Buytenhek <buytenh@wantstofly.org> 2012-09-04 05:43:27 --- I have committed the fix to the ivykis master and stable-v0.30 branches. I'll release 0.30.3 by the end of this week or so if nothing else pops up before that time.
This is the fix I committed to stable-v0.30: commit 84963e1987d38bd8c77dd74dcacdfe9344fc0fe8 Author: Lennert Buytenhek <buytenh@wantstofly.org> Date: Mon Sep 3 19:01:27 2012 +0200 spinlock.h: Use PTHREAD_PROCESS_SHARED for pthread-backed spinlocks. iv_signal maintains an AVL tree of registered signal interests, which is protected from concurrent modifications as well as from lookup versus modification races by a spinlock. To be able to reset the disposition of each signal for which there is an iv_signal object registered back to SIG_DFL in the child process after fork(), we have to walk the AVL tree from the child process, but this requires that the child sees a consistent version of the AVL tree, and that requires that we don't add or remove signal interests in one thread while calling fork() in another thread in the parent process. To guarantee the consistency of the AVL tree data structure across fork() calls, iv_signal registers atfork handlers which lock the spinlock in the parent process before the fork() happens, and unlock the spinlock in both the parent process and the child process after the fork() completes. However, for this to work properly, the spinlock that iv_signal uses must be initialized as a shared spinlock (PTHREAD_PROCESS_SHARED) instead of as a process private spinlock (PTHREAD_PROCESS_PRIVATE) as is done currently. This trips up at least FreeBSD, as FreeBSD's libpthread apparently has different implementations for process private spinlocks and shared spinlocks, and trying to lock an unlocked process private spinlock in a fork()ed child process causes the child to go into an infinite loop. Fix this by having spinlock.h initialize pthread spinlocks as shared spinlocks. This was showing up as an issue on FreeBSD builds of syslog-ng. Reported-by: Cy Schubert <cy@FreeBSD.org> Tested-by: Gergely Nagy <algernon@balabit.hu> Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org> diff --git a/modules/spinlock.h b/modules/spinlock.h index 1978317..6451f85 100644 --- a/modules/spinlock.h +++ b/modules/spinlock.h @@ -25,7 +25,7 @@ static inline void spin_init(spinlock_t *lock) { - pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init(lock, PTHREAD_PROCESS_SHARED); } static inline void spin_lock(spinlock_t *lock)