AIX 4.3.3 + sshd = bug

Sandor W. Sklar ssklar at
Tue Mar 6 05:32:24 EST 2001


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 
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>
     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 */

     strcpy(str,"this is the last thing you will see if sshd is broken.\n");
         fprintf(stderr,"len = %d str = %s",strlen(str),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 

   +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.


sandor w. sklar       
unix systems administrator      polya hall, 255 panama -- mc: 4136
stanford university itss-css    mailto:ssklar at

More information about the openssh-unix-dev mailing list