Date: Sun, 1 Nov 1998 21:32:50 EST
From: Andy Church <[email protected]>
To: [email protected]Subject: ssh-1.2.26 buffer overflow patch
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
[email protected] | 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);