Hello,
I believe that there is a bug in OpenSSH that affects its usage on
AIX 4.3.3 - Maintenance Level 3 and higher. This bug was introduced
by a change by IBM in the "/usr/lib/drivers/ptydd" driver, and it
affected IBM's own telnetd daemon (reference
<http://techsupport.services.ibm.com/rs6000/aix.uhuic_getrec?args=DVhuron.boulder.ibm.com+DBAIX+DA69743+STIY09667+USbin>).
However, IBM chose not to fix the cause of the problem, but to
instead modify telnetd to deal with the issue.
The problem occurs in the sshd program; when a program on the server
writes a zero-length string to the terminal, the sshd daemon abruptly
closes the connection, logging no information. The following code
causes the problem to exhibit itself:
#include <stdio.h>
#include <fcntl.h>
main()
{
int tty_fd;
int old_tty_fd;
int old_stdout_fd;
char str[100];
old_tty_fd = open("/dev/tty",O_RDWR);
tty_fd = dup(old_tty_fd); /* 1 will be /dev/tty */
close(old_tty_fd);
strcpy(str,"this is the last thing you will see if sshd is
broken.\n");
fprintf(stderr,"len = %d str = %s",strlen(str),str);
write(tty_fd,str,strlen(str));
strcpy(str,"");
fprintf(stderr,"len = %d str = %s\n",strlen(str),str);
write(tty_fd,str,strlen(str)); /* we die here on 433 */
fprintf(stderr,"if you can read this then all is good.\n");
}
This bug pops up with both OpenSSH 2.3.0.p1 and 2.5.1p1 (and with the
commercial ssh 1.2.26), but only when the daemon is running on
4.3.3-ML3 or higher. The same daemon works fine on AIX 4.3.2-ML2,
and 4.3.3 with no ML applied.
With a lot of help, I figured that the cause of the disconnect is a
comparison in the "serverloop.c" file. Changing the comparison
operator from a "<=" to just a "<" in the serverloop.c
file fixes the
issue. Here is the code block (taken from the 2.3.0p1 source
distribution:
+304 /* Read and buffer any available stdout data from the
program. */
+305 if (!fdout_eof && FD_ISSET(fdout, readset)) {
+306 len = read(fdout, buf, sizeof(buf));
+307 if (len < 0 && (errno == EINTR || errno ==
EAGAIN)) {
+308 /* do nothing */
+309 } else if (len <= 0) {
+310 fdout_eof = 1;
+311 } else {
+312 buffer_append(&stdout_buffer, buf, len);
+313 fdout_bytes += len;
+314 }
Line # 309 needs to be changed to ...
+309 } else if (len < 0) {
Making the above change in the 2.3.0p1 and the 2.5.1p1 source
distributions solves the problem, however, I don't know if there
might be any other ill effect, or if the change will have an effect
on other platforms.
Thanks,
--Sandy
--
sandor w. sklar http://lindy.stanford.edu/~ssklar/
unix systems administrator polya hall, 255 panama -- mc: 4136
stanford university itss-css mailto:ssklar at stanford.edu