Bugtraq mailing list archives

ssh-1.2.26 buffer overflow patch


From: achurch () DRAGONFIRE NET (Andy Church)
Date: Sun, 1 Nov 1998 21:32:50 EST


     For those with OS's that have snprintf() in libc (I think this
includes at least Linux and FreeBSD--I don't know about others), the patch
below fixes the overflows mentioned in the recent Rootshell advisory about
ssh.  If you're on a system that doesn't have snprintf(), you can probably
do something with support/vsnprintf.c from wu-ftpd if you want to avoid the
stupid licensing restrictions on ssh 2.0.x.

     And as a comment on SSH Communications' damage-control statement of
"[n]o buffer overflows nor any other security bugs were found":

[login.c:538]
log_msg("putuserattr S_LASTTTY %.900s failed: %.100s", /*...*/);

[log-server.c:130]
void log_msg(const char *fmt, ...)
{
  char buf[1024];
  /*...*/
  vsprintf(buf, fmt, args);
  /*...*/
}

Granted, I haven't checked whether this is exploitable, but I could never
call that secure.  (Count the bytes.)

  --Andy Church                    | If Bell Atlantic really is the heart
    achurch () dragonfire net         | of communication, then it desperately
    http://achurch.dragonfire.net/ | needs a quadruple bypass.

---------------------------------------------------------------------------

*** log-server.c.old    Wed Jul  8 12:40:36 1998
--- log-server.c        Sun Nov  1 20:37:32 1998
***************
*** 134,140 ****
    if (log_quiet)
      return;
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "log: %s\n", buf);
--- 134,140 ----
    if (log_quiet)
      return;
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "log: %s\n", buf);
***************
*** 175,181 ****
    if (log_quiet)
      return;
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "log: %s\n", buf);
--- 175,181 ----
    if (log_quiet)
      return;
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "log: %s\n", buf);
***************
*** 191,197 ****
    if (!log_debug || log_quiet)
      return;
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "debug: %s\n", buf);
--- 191,197 ----
    if (!log_debug || log_quiet)
      return;
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "debug: %s\n", buf);
***************
*** 207,213 ****
    if (log_quiet)
      return;
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "error: %s\n", buf);
--- 207,213 ----
    if (log_quiet)
      return;
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "error: %s\n", buf);
***************
*** 302,308 ****
    if (log_quiet)
      exit(1);
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "fatal: %s\n", buf);
--- 302,308 ----
    if (log_quiet)
      exit(1);
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "fatal: %s\n", buf);
***************
*** 321,327 ****
    if (log_quiet)
      exit(1);
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "fatal: %s\n", buf);
--- 321,327 ----
    if (log_quiet)
      exit(1);
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    if (log_on_stderr)
      fprintf(stderr, "fatal: %s\n", buf);
*** packet.c.old        Wed Jul  8 12:40:37 1998
--- packet.c    Sun Nov  1 20:37:32 1998
***************
*** 693,699 ****
    va_list args;

    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);

    packet_start(SSH_MSG_DEBUG);
--- 693,699 ----
    va_list args;

    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);

    packet_start(SSH_MSG_DEBUG);
***************
*** 719,725 ****
    /* Format the message.  Note that the caller must make sure the message
       is of limited size. */
    va_start(args, fmt);
!   vsprintf(buf, fmt, args);
    va_end(args);

    /* Send the disconnect message to the other side, and wait for it to get
--- 719,725 ----
    /* Format the message.  Note that the caller must make sure the message
       is of limited size. */
    va_start(args, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);

    /* Send the disconnect message to the other side, and wait for it to get
*** scp.c.old   Sun Sep 13 16:04:50 1998
--- scp.c       Sun Nov  1 20:37:32 1998
***************
*** 332,338 ****
    char buf[1024];

    va_start(ap, fmt);
!   vsprintf(buf, fmt, ap);
    va_end(ap);
    fprintf(stderr, "%s\n", buf);
    exit(255);
--- 332,338 ----
    char buf[1024];

    va_start(ap, fmt);
!   vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    fprintf(stderr, "%s\n", buf);
    exit(255);



Current thread: