[15612] in bugtraq
Re: WuFTPD: Providing *remote* root since at least1994
daemon@ATHENA.MIT.EDU (Alan J Rosenthal)
Sun Jul 2 16:32:51 2000
Message-Id: <20000630213520.2236F186AD@atlas.dgp.toronto.edu>
Date: Fri, 30 Jun 2000 17:35:20 -0400
Reply-To: Alan J Rosenthal <flaps@DGP.TORONTO.EDU>
From: Alan J Rosenthal <flaps@DGP.TORONTO.EDU>
To: BUGTRAQ@SECURITYFOCUS.COM
>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.