This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bug in Newlib's snprintf implementation


On Feb 23 04:34, Sebastian Huber wrote:
> ----- Am 23. Feb 2018 um 4:00 schrieb Dominik Maier domenukk@gmail.com:
> 
> > Hello,
> > 
> > I've already reported this over at MinGW but since I could also
> > reproduce the Bug in Cygwin and understand both use Newlib, I figured
> > I'd post this here, too.
> > 
> > The snprintf implementation is not compliant. This can lead to bugs and
> > memory corruptions.
> > 
> > A simple PoC is the following
> > 
> >    char buf[4];
> >    snprintf(buf, 4,"te%s", "st");
> >    printf("%s", buf);
> > 
> > It should print "tes" (0-terminated) but instad prints "test" and
> > appends random memory (tested in cygwin and mingw).
> > 
> 
> I cannot reproduce this issue on RTEMS. Her buf is "tes\0" and the return value is 4.

Tested on most recent Cygwin 2.10.0, x86 and x86_64.  Both return
"tes\0" and the return value is 4.

> > Then len field in this case is 4, which is correct (apart from the
> > missing zero termination), however it will return an error (-1) for any
> > larger input.
> 
> It should return the actual size of the produced string and not -1.

Slight correction: snprintf returns the size of the string it would
have produced if it hadn't truncated the output.  So a size value
of 4 ("test" would have been the desired result) is correct.

Having said that, I get the wrong result Dominik describes if I build
the test application as a MingW-w64 application.  In that case, snprintf
returns 4 (correct) but the string is not \0 terminated, rather the
word "test" is fully printed and then some.

So the bug is *not* in Newlib or, FWIW, Cygwin, but rather in the
Mingw-w64 library.  You should bring this to the attention of the
Mingw-w64 folks.

Here's another, more complete testcase to verify:

$ cat > poc.c << EOF
#include <stdio.h>
#include <string.h>

int
main ()
{
    char buf[8];
    int ret;

    memset (buf, 'X', 7);
    buf[7] = '\0';
    ret = snprintf(buf, 4,"te%s", "st");
    printf("%d %s\n", ret, buf);
}
EOF
$ gcc -g -o poc poc.c				# Create Cygwin binary
$ ./poc
4 tes
$ x86_64-w64-mingw32-gcc -g -o poc poc.c	# Create MingW binary
$ ./poc
4 testXXX


Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat

Attachment: signature.asc
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]