Subject: Re: proposal: disable *printf %n specifier in libc in NetBSD 1.5
To: None <>
From: Chris G. Demetriou <>
List: tech-userlevel
Date: 09/11/2000 12:31:48
Bill Sommerfeld <> writes:
> %n allows a error which would otherwise allow for a *read* of an
> arbitrary address (and likely program-terminating core dump) into one
> which allows arbitrary writes into arbitrary locations, allowing
> complete subversion of program behavior.

an error fundamentally caused by inadequate checking in the program.

It should be rectified by adequate checking in the program, and, if
there are no other negative implications by the system
(incl. libraries) if possible.

However, in this case, there are negative implications.

For instance, a program provides adequate checking of buffer lengths
by using snprintf() et al.

This wasn't accomplished by modifying the standard behaviour of
sprintf() on an unsuspecting (and standards-conforming, and
properly-written) application.

> program-crashing denials of service are significantly less severe than
> holes which allow an attacker to patch an arbitrary location to an
> arbitrary value and/or execute arbitrary code.

that can only be said in specific cases, of course; it depends on the
service, or which type of hole can be explioted, or both.

The issue here is that you want to kill standards conformance to work
around a specific hole which is simply a specific case of a more
general programming problem which, taken as a whole, still remains a
serious problem after your "fix."

The general problem is that user input is being used without being
adequately sanity checked.  That causes problems for %n, but it also
causes problems for %s and other format strings, and wouldn't be a
problem at all were the program correctly written.

> I have no objection to continuing to support %n in
> compile-time-constant format strings, as long as we're protected from
> %n exploits in run-time variable format strings.

how about the other problems caused by bogus input?

"I can't write programs correctly, and the library takes case of this
case for me, it should make the rest work right too!!!"

It's a stupid argument for a programmer to make, but the answer in
_all_ cases should be "WRITE YOUR PROGRAM CORRECTLY, or if you must,
try disabling some more dangerous library features by doing ...," if
the alternative is to break portable, standards-conforming programs.