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 achurchat_private | 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);
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:21:35 PDT