Two patches for OpenSSH 3.1p1 (fwd)
Ben Lindstrom
mouring at etoh.eviladmin.org
Sat Mar 30 05:26:32 EST 2002
Can I get people from other platforms to test the waitpid.patch to see
if it solves hang-on-exit on their platform?
I can confirm Solaris at this moment (but I've not done heavy testing at
this moment) that is works like a charm (Solaris 7). It handles 'sleep
90&' vs 'nohup sleep 90&' correctly (killed, vs left).
thanks.
- Ben
---------- Forwarded message ----------
Date: Tue, 26 Mar 2002 22:21:31 +0100 (MET)
From: Peter Eriksson <peter at ifm.liu.se>
To: openssh-unix-dev at mindrot.org
Subject: Two patches for OpenSSH 3.1p1
Please find enclosed two patches for OpenSSH 3.1p1.
The first patch solves a problem where sessions will be left "hanging"
when you normally exit from a ssh shell (for example by logging out from
the remote host via "exit" or "logout"). The problem seems to be that sshd
(and some other parts of OpenSSH) doesn't check the return code and errno
from waitpid() for errno == EINTR and thus fails to collect the started
subprocess correctly. This problem occurs atleast on Solaris 2 and UNICOS
systems but it should probably exist on all other SysV based systems...
(It doesn't occur all the time so it can be quite hard to test for).
The other patch adds a "-I" command line option to allow sshd to be
correctly started (and automatically restarted) by "init" (via the
/etc/inittab file) on systems with a SysV-style "init".
It is *not* sufficent to just use the "-D" (no daemon) flag since that
doesn't correctly handle log file output, closing of stdin/stdout/stderr
or the setsid() call to drop the controlling TTY.
Trying to start sshd via inittab and using "-D" will cause sshd to
terminate if the Console connection (for example if using a serial
terminal) gets dropped...
--
Peter Eriksson <peter at ifm.liu.se> Phone: +46 13 28 2786
Computer Systems Manager/BOFH Cell/GSM: +46 705 18 2786
Physics Department, Linköping University Room: Building F, F203
SE-581 83 Linköping, Sweden http://www.ifm.liu.se/~peter
-------------- next part --------------
diff -r -c openssh-3.1p1/entropy.c openssh-3.1p1-peter/entropy.c
*** openssh-3.1p1/entropy.c Tue Jan 22 11:57:54 2002
--- openssh-3.1p1-peter/entropy.c Mon Mar 18 22:00:10 2002
***************
*** 110,118 ****
close(p[0]);
! if (waitpid(pid, &ret, 0) == -1)
! fatal("Couldn't wait for ssh-rand-helper completion: %s",
strerror(errno));
/* We don't mind if the child exits upon a SIGPIPE */
if (!WIFEXITED(ret) &&
--- 110,124 ----
close(p[0]);
! {
! int code;
!
! while ((code = waitpid(pid, &ret, 0)) == -1 && errno == EINTR)
! ;
! if (code < 0)
! fatal("Couldn't wait for ssh-rand-helper completion: %s",
strerror(errno));
+ }
/* We don't mind if the child exits upon a SIGPIPE */
if (!WIFEXITED(ret) &&
Only in openssh-3.1p1/scard: Ssh.bin
diff -r -c openssh-3.1p1/serverloop.c openssh-3.1p1-peter/serverloop.c
*** openssh-3.1p1/serverloop.c Fri Feb 8 12:07:17 2002
--- openssh-3.1p1-peter/serverloop.c Mon Mar 18 22:01:02 2002
***************
*** 673,679 ****
/* We no longer want our SIGCHLD handler to be called. */
mysignal(SIGCHLD, SIG_DFL);
! wait_pid = waitpid(-1, &wait_status, 0);
if (wait_pid == -1)
packet_disconnect("wait: %.100s", strerror(errno));
else if (wait_pid != pid)
--- 673,681 ----
/* We no longer want our SIGCHLD handler to be called. */
mysignal(SIGCHLD, SIG_DFL);
! while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0 && errno == EINTR)
! ;
!
if (wait_pid == -1)
packet_disconnect("wait: %.100s", strerror(errno));
else if (wait_pid != pid)
diff -r -c openssh-3.1p1/sftp-int.c openssh-3.1p1-peter/sftp-int.c
*** openssh-3.1p1/sftp-int.c Wed Feb 13 04:10:33 2002
--- openssh-3.1p1-peter/sftp-int.c Mon Mar 18 22:02:38 2002
***************
*** 176,183 ****
strerror(errno));
_exit(1);
}
! if (waitpid(pid, &status, 0) == -1)
fatal("Couldn't wait for child: %s", strerror(errno));
if (!WIFEXITED(status))
error("Shell exited abormally");
else if (WEXITSTATUS(status))
--- 176,192 ----
strerror(errno));
_exit(1);
}
! {
! int code;
!
!
! while ((code = waitpid(pid, &status, 0)) == -1 && errno == EINTR)
! ;
!
! if (code < 0)
fatal("Couldn't wait for child: %s", strerror(errno));
+ }
+
if (!WIFEXITED(status))
error("Shell exited abormally");
else if (WEXITSTATUS(status))
diff -r -c openssh-3.1p1/sftp.c openssh-3.1p1-peter/sftp.c
*** openssh-3.1p1/sftp.c Wed Feb 13 04:03:57 2002
--- openssh-3.1p1-peter/sftp.c Mon Mar 18 22:01:49 2002
***************
*** 246,253 ****
if (infile != stdin)
fclose(infile);
! if (waitpid(sshpid, NULL, 0) == -1)
fatal("Couldn't wait for ssh process: %s", strerror(errno));
exit(0);
}
--- 246,261 ----
if (infile != stdin)
fclose(infile);
! {
! int code;
!
!
! while ((code = waitpid(sshpid, NULL, 0)) == -1 && errno == EINTR)
! ;
!
! if (code < 0)
fatal("Couldn't wait for ssh process: %s", strerror(errno));
+ }
exit(0);
}
diff -r -c openssh-3.1p1/ssh-rand-helper.c openssh-3.1p1-peter/ssh-rand-helper.c
*** openssh-3.1p1/ssh-rand-helper.c Sun Feb 10 08:32:30 2002
--- openssh-3.1p1-peter/ssh-rand-helper.c Mon Mar 18 22:04:34 2002
***************
*** 389,398 ****
debug3("Time elapsed: %d msec", msec_elapsed);
! if (waitpid(pid, &status, 0) == -1) {
error("Couldn't wait for child '%s' completion: %s",
src->cmdstring, strerror(errno));
return 0.0;
}
RAND_add(&status, sizeof(&status), 0.0);
--- 389,406 ----
debug3("Time elapsed: %d msec", msec_elapsed);
! {
! int code;
!
! while ((code = waitpid(pid, &status, 0)) == -1 && errno == EINTR)
! ;
!
! if (code < 0)
! {
error("Couldn't wait for child '%s' completion: %s",
src->cmdstring, strerror(errno));
return 0.0;
+ }
}
RAND_add(&status, sizeof(&status), 0.0);
diff -r -c openssh-3.1p1/sshd.c openssh-3.1p1-peter/sshd.c
*** openssh-3.1p1/sshd.c Tue Mar 5 02:31:30 2002
--- openssh-3.1p1-peter/sshd.c Mon Mar 18 22:03:37 2002
***************
*** 264,273 ****
main_sigchld_handler(int sig)
{
int save_errno = errno;
! int status;
! while (waitpid(-1, &status, WNOHANG) > 0)
! ;
signal(SIGCHLD, main_sigchld_handler);
errno = save_errno;
--- 264,274 ----
main_sigchld_handler(int sig)
{
int save_errno = errno;
! int status, code;
!
! while ((code = waitpid(-1, &status, WNOHANG)) < 0 && errno == EINTR || code > 0)
! ;
signal(SIGCHLD, main_sigchld_handler);
errno = save_errno;
More information about the openssh-unix-dev
mailing list