Platform independent allocating sprintf (was Re: buffer overrun

From: Forrest J. Cavalier III (forrest@mibsoftware.com)
Date: 02/25/03

  • Next message: Mandrake Linux Security Team: "MDKSA-2003:023 - Updated lynx packages fix CRLF injection vulnerability"
    Date: Mon, 24 Feb 2003 18:30:16 -0500 (EST)
    From: "Forrest J. Cavalier III" <forrest@mibsoftware.com>
    To: bugtraq@securityfocus.com
    
    

    Thamer Al-Harbash <tmh@whitefang.com> wrote

    > 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.
    >
    [snip]
    >
    > 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.

    If you can't use the allocating vasprintf() and care about security,
    tmpfile() and vfprintf() are available on just about every
    platform, including Windows.

    You have to trust tmpfile() and have a vfprintf() which returns
    a negative integer on filesystem errors (and it will, if it
    complies with IEEE Std 1003.1-2001)

    For speedup, you can "special case" some of the most common % formatting
    (%%, %s, %d, and %u) and use the tmpfile() strategy only when there are
    field width specifiers and unrecognized format specifiers. When you
    do that, the performance is usually acceptable, and you can still use
    all of the "special" formatting you often get with localized fprintf()s.

    Librock has reusable code which uses just that strategy to implement a
    platform-independent "printf into an allocated string". Docs and
    source at:
       http://www.mibsoftware.com/librock/text/vastrprintf.htm

    This function follows the typical easy-to-reuse semantics
    and licensing of the librock_astr functions:

        char *asz = 0; /* Must initialize to 0! */
        librock_astrprintf(&asz,"This is a test %s\n",pszLongString);
        . . .
        librock_astrcat(&asz,"\nAppending another long string....");
        . . .
        librock_astrfree(&asz);

    (The librock source code is Free. No cost. BSD-ish license with no
    advertising clause.)

    Hope it helps!

    Forrest Cavalier III, owner Mib Software



    Relevant Pages

    • Re: buffer overrun in zlib 1.1.4
      ... > vsnprintfinstead of vsprintf(), but this is not enabled by default, ... > platforms without vsnprintf() are supposed to do. ... long strings will be silently truncated and overflows are ... Unexpected truncation ...
      (Bugtraq)
    • Re: vsprintf without vsnprintf
      ... I'm on a platform that has vsprintf but not vsnprintf. ... Is there anyway I can limit vsprintf or know in advance the required buffer ... Valgrind doesn't find overruns on automatic ...
      (comp.lang.c)
    • Re: vsprintf without vsnprintf
      ... I'm on a platform that has vsprintf but not vsnprintf. ... I suspect the former function is causing a buffer overflow but I've been unable to prove it so far. ... Is there anyway I can limit vsprintf or know in advance the required buffer size ?!? ... va_list arg) { ...
      (comp.lang.c)
    • Re: Query regarding thread safety of few libc stdio functions
      ... >Which ensures that they are thread safe. ... >Why is the same case not followed for eg with vsnprintf or vsprintf ... vsnprintf and vsprintf use a on stack FILE structure, ...
      (freebsd-current)