Issue with child process exits

Rick Houlihan rhouliha at us.ibm.com
Tue Mar 24 11:05:34 EST 2009


I recently started building a simulator using honeyd as an IP emulator and 
experienced an issue with hangs on exit from ssh and sftp sessions.  A 
quick look at the OpenSSH source code revealed the following:

In serverloop.c there is a signal handler defined for SIGCHLD as follows:








static void 
sigchld_handler(int sig) 
{ 
int save_errno = errno; 
debug("Received SIGCHLD."); 
child_terminated = 1; 
#ifndef _UNICOS 
mysignal(SIGCHLD, sigchld_handler); 
#endif 
notify_parent(); 
errno = save_errno; 
} 




As far as I can tell the primary purpose of this method is to set a value 
for child_terminated which is referenced by the following method:








static void 
collect_children(void) 
{ 
#ifndef HAVE_NETWARE 
pid_t pid; 
sigset_t oset, nset; 
int status; 

/* block SIGCHLD while we check for dead children */ 
sigemptyset(&nset); 
sigaddset(&nset, SIGCHLD); 
sigprocmask(SIG_BLOCK, &nset, &oset); 
if (child_terminated) { 
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 
(pid < 0 && errno == EINTR)) 
if (pid > 0) 
session_close_by_pid(pid, status); 
child_terminated = 0; 
} 
sigprocmask(SIG_SETMASK, &oset, NULL); 
#endif 
} 




This code above seems quite odd in that it really should not be required 
to check the value of child_terminated before calling waitpid since 
WNOHANG is specified. If no child has had a state change then waitpid will 
return 0 which means that the while loop is not executed. 

The issue I was seeing is that SIGCHLD was not getting handled when sshd 
was started by honeyd using the -i flag.  I commented out the if test on 
child_terminated and everything then worked as expected.  My experience in 
general is that it is not good practice to rely on signals for IPC as they 
are not always reliable.  In any case, I am not sure what the reason might 
be for such a convoluted mechanism just to avoid calling waitpid.  Perhaps 
this code should just be modified to call waitpid whenever 
collect_children is executed?

RH


More information about the openssh-unix-dev mailing list