Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Dec 2005 06:18:30 +1100
From:      Peter Jeremy <PeterJeremy@optushome.com.au>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        arch@freebsd.org
Subject:   Re: printf behaviour with illegal or malformed format string
Message-ID:  <20051212191830.GD74684@cirb503493.alcatel.com.au>
In-Reply-To: <1023.1134389663@critter.freebsd.dk>
References:  <1023.1134389663@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2005-Dec-12 13:14:23 +0100, Poul-Henning Kamp wrote:
>The context for the above is that I'm working on adding extensibility
>to our printf, compatible with the GLIBC (see 12.13 in the glibc
>manual).

http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
for anyone else wanting to see what it does.

>  Obviously, gcc cannot compile-time check such extensions
>for us, and therefore the question gains a bit more relevance.

There doesn't even appear to be a defined way of determining whether
extensions are supported.  Since not all libc's support printf
extensions, an application that wants to use them has to confirm that
they work and the only way to do this appears to be to try it and see
what happens (either at runtime, or during a autoconf-style configuration
process).

>Another alternative is to spit out the format string unformatted,
>possibly with an attached notice, but this doesn't really seem to
>help anybody either, but at least indicates what the problem is.

xterm does (or did) this if it is running as root and the format
string contains conversion specification that it thinks are suspicious.

>I'm leaning towards doing what phkmalloc has migrated to over time:
>Make a variable which can select between "normal/paranoia" and force
>it to paranoia for (uid==0 || gid==0 || setuid || setgid).
>
>If the variable is set, a bogus format string will result in abort(2).

set{u,g}id programs won't dump core so just abort(2)ing leaves no
trace of what went wrong.  This makes finding the problem more
difficult.  Even for {u,g}id == 0 programs, it would be nice to have
something reported (but see below).  Note that this behaviour has
implications for programs that are trying to determine if extensions
are supported or not.

>If it is not set, the format string will be output unformatted in
>the message "WARNING: Illegal printf() format string: \"...\".

Since this check presumably applies to the entire *printf() family,
where do you report the error for {s,f}printf()?

What do you define as an "illegal printf() format string"?  I can
think of four possible categories:
1) Using a nonsense value before '$', eg "%12345$d"
2) Having an invalid modifier on a builtin conversion specifier, eg "%hf"
3) Using an undefined conversion specified, eg '%W'
4) Having an invalid modifier on a user-specified conversion specifier

The last category is particularly problematic because the glibc
interface does not have any way to identify this error.  The glibc
documentation just states that the output handler conversion function
(printf_function) should return a negative number if an error occurs
so it's not possible to distinguish an invalid modifier from an I/O
error or invalid argument.

-- 
Peter Jeremy



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051212191830.GD74684>