Bugtraq mailing list archives

Re: WuFTPD: Providing *remote* root since at least1994


From: flaps () DGP TORONTO EDU (Alan J Rosenthal)
Date: Fri, 30 Jun 2000 17:35:20 -0400


Actually many people blame sprintf usage as a potential source
for buffer overflow exploits, yet :

char buff[BUFSIZ];
sprintf(buff, "%.*s", BUFSIZ, "string");

The problem with this is that it's difficult to get it right, especially when
you have things like "%d" involved.  For example, you're off by one above.
You should have used BUFSIZ-1 as the size argument.

This also involves error-prone counting when the format string is something
like "blah blah %.??s blah", where if buf is char[80] you'll need to make
that something like "%.64s".  I thought that this error-prone manual counting
of characters in strings ended with the advent of quote-delimited strings
in Fortran IV in around 1970.

(Incidentally, BUFSIZ in stdio.h is *not* intended as a suitable size for any
variable named "buf" but rather as the size of buffer to allocate if you're
going to pass something to setbuf().  BUFSIZ can be small, and apparently
was on at least one wacky but legal implementation.)

IMHO it's very easy to avoid buffer overflows when writing critical programs
just by keeping in mind [to check sizes]

Agreed, except that sometimes this precludes the use of sprintf or requires
extra large string space for the buffer to cover uncertainty (especially
around "%d").  Most of all, there's the question of being able to see locally
that code is correct.  snprintf(buf, sizeof buf, "%d", i) is more easily seen
to be correct than sprintf(buf, "%d", i) when buf is char[21] (or is that
22:-) ).  There's also the question of the avoidance of off-by-one errors.
You've shown with your example that off-by-one errors are easy with the
idiom you suggest.


Current thread: