[Re-posting with a more useful subject heading and with additional detail.]
At my employer we have a problem with CFEngine which follows the following scenario.
* cf-execd is for some reason running with SIGPIPE blocked.
* CFEngine restarts sshd (and other server processes) which consequently also have SIGPIPE blocked.
* A user logs in to the machine via sshd and gets a bash shell which also has SIGPIPE blocked.
* The user enters a sudo or strace command and presses Enter.
* Bash creates a child process which starts by looking stuff up via nss_ldap which results in an LDAPS query using OpenSSL.
* In the course of its normal operation this query triggers a SIGPIPE which can't be delivered (because SIGPIPE is blocked) and so becomes pending.
* In its initialisation phase sudo or strace unblocks SIGPIPE.
* The SIGPIPE is delivered to sudo or strace which immediately exits.
Perhaps sudo and strace should clear signals before unblocking them, not sure. Regardless, CFEngine should not be spawning children that have SIGPIPE blocked. CFEngine spawns children that have SIGPIPE blocked because it has SIGPIPE blocked itself. I don't know how it comes to be the case that cf-execd is running with SIGPIPE blocked. If CFEngine is responsible for this then I would be inclined to think that this is a bug.
The following workaround has been adopted for this problem.
cron.d/fixsigblock.cron:
*/15 * * * * root /usr/local/sbin/fixsigblock.sh
The script /usr/local/sbin/fixsigblock.sh checks to see if cf-execd is running with the SIGPIPE bit set in its sigblk mask as read from the line in /proc/<pid>/status starting with 'SigBlk'. If so then it restarts the CFEngine daemons using the /etc/init.d/cfengine3 initscript. Because cron was started at boot with SIGPIPE unblocked, its children also have SIGPIPE unblocked.
Looking at the 3.5.1 and at the current CFEngine source code I see that SIGPIPE gets blocked in client_code.c. I don't see it being unblocked anywhere.
static AgentConnection *ServerConnection(const char *server, FileCopy fc, int *err, int s)
{
AgentConnection *conn = NULL;
int ret;
*err = 0;
#if !defined(__MINGW32__)
signal(SIGPIPE, SIG_IGN);
#endif /* !__MINGW32__ */
#if !defined(__MINGW32__)
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
#endif
Is there a bug here?