Subject: Re: proposal: disable *printf %n specifier in libc in NetBSD 1.5
To: None <sommerfeld@orchard.arlington.ma.us>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-userlevel
Date: 09/11/2000 11:25:06
Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us> writes:
> > It's not clear to me that losing standards conformance to make
> > admittedly-broken programs somewhat more secure is either a good
> > thing, or in keeping with the principle of least surprise.
> 
> the same argument could be used against the introduction of
> snprintf(); applications *should* know how much space they'll need in
> advance.

only if they, for instance, do strlen on their input.

It's impossible for user input to introduce a variation other than
result length on:

	sprintf(buf, "%s", userdata);

To save the need for that strlen and possible dynamic buffer
allocation, snprintf() provides a very useful feature.


> %n turns an otherwise "safe" interface into an interface as dangerous
> as gets().

This is rubbish.

gets() has, effectively, arbitrary result, in the face of a malicious
user.

printf() et al with %n have very well defined result, and it's never
something that a malicious user should be able to trigger _unless_ the
application is broken and does something like:

	printf(userdata, arg1, arg2, ...)

that type of use of user data without checking is fundamentally broken
to begin with.  There's no reason to believe that the user data will
have any relation to the rest of the arguments you've provided.
(Indeed, that is the basic cause of problem with %n, as i understand
them.)  There's nothing to say that the user won't provide 500 %s
specifiers, or %n or ... who knows what.

It is fundamentally unsafe to pass user data as the format string to
printf.  %n may make this exploitable in a way that can set a value in
the program, but the fundamental issue is still there and should be
addressed by fixing the issue, not by band-aiding printf() et al. in a
non-standard way.



cgd