Re: better snprintf replacement, anyone?

Theo de Raadt (deraadt@CVS.OPENBSD.ORG)
Tue, 22 Jul 1997 00:57:11 -0600

> On Sat, 19 Jul 1997, Theo de Raadt wrote:
> >Quite often I find people saying to me "Why do you use snprintf() all
> >over the place to avoid buffer overflows, and not try to use other
> >techniques. Using snprintf() makes it hard for us to port the code to
> >legacy systems."
>
> It's still not clear to me why people only suggest snprintf().
> I would imagine that there are only a few cases were a program coulnd't
> pre-determine the length of a string that would be generated by sprintf()
> and malloc() enough memory to contain it all. Yes, it's a little extra
> work to strlen() all the variables you're pulling in, but you ensure that
> you have a large enough buffer, you eliminate the buffer overflow problem,
> and you don't truncate the string. Is malloc()-ing the memory *that*
> inefficient? Less efficient than the scanning and parsing snprintf()
> must do to the format string?

The reason is simple.

snprintf is easy to use.

Let me ask you a question. If checking the arguments before calling
sprintf is so easy, why did only 1 on 20 programs do so? Why did they
all overflow? Why were 4 people kept busy for almost a year fixing
buffer overflows?

Why, perhaps 10 years after buffer overflows became well known, did
people persist in not checking the buffer sizes before calling
sprintf?

Let me give you an example of what you suggest:

if (strlen(a) + 1 + 10 + 3 + 1 + 10 + 4*sizeof(long) + 1 + strlen(b) +
1 + strlen(c) + 2 >= sizeof buf);
sprintf(buf, "%s %d see %d %lx %s %s\n", a, i, j, p,
b, c);
else
goto bail; /* I really just wanted to truncate the string... */

The reason is simple.

If it isn't easy to write secure code, people will not write secure
code.

And anyways, in 99% of the cases a truncation is desirable, because
anything else is an error we don't know how to deal well with. I have
run into very few cases where truncation wasn't acceptable behaviour.