Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 27 Feb 2019 11:34:20 -0500
From: Rich Felker <>
Subject: Re: C Annex K safe C functions

On Wed, Feb 27, 2019 at 08:11:53AM -0500, Rich Felker wrote:
> On Wed, Feb 27, 2019 at 10:30:52AM +0700, Jonny Grant wrote:
> > Hello
> > Not on the list, so please cc me in replies.
> > Any plans to support Annex K?
> > Those safe functions are great, strncpy_s etc
> No, and there's been considerable amounts of stuff written on this in
> the past. I'll try to give you a good summary later. The reply so far
> by Szabolcs Nagy is a good start.

Here's what comes to mind about the technical and social reasons
behind not adopting Annex K:

1. The Annex K interfaces are clearly inspired by (even named
identically to) the corresponding *_s interfaces provided by MSVC.
However, the MSVC functions don't actually conform to the
specification in Annex K, due to some subtle breakage in types (IIRC
the rsize_t stuff, possibly other things too). Thus there are actually
two slightly incompatible sets of functions with the same names. This
is generally a strong criterion for exclusion from musl, unless one of
the standards we aim to support mandates the presence of the functions
with this problem (like strerror_r).

2. The handling of "runtime constraint violation" and the ability to
customize the handler for it is highly problematic. Code using the
Annex K functions can neither rely on a particular default handling of
these errors, nor can it set the handling it wants unless it's global
initialization code for the whole application, since the runtime
constraint handler is global state that can't be set in a thread-safe
or library-safe manner. Thus, to use these functions safely, you must
both check for the erroneous conditions before making the call (since,
for one choice of handler, the call could abort your program if it
detects them), and you must check for an error return from the
function (since, for a different choice of handler, it might just
return an error, and if you don't check for that yourself, your
program could continue running in an unsafe state).

3. In order to provide any safety over the standard functions they
"replace", the Annex K functions rely on the caller to provide
accurate information about the sizes of buffers, etc. in the
additional function arguments. There's no good reason to believe that
the programmer will get these arguments right when they consistently
fail to get the arguments to the standard functions right. For
example, there's no reason to believe programmers won't just call
memcpy_s(dest, n, src, n) instead of going back to some better
authoritative source for the size of the dest buffer. In many (most?)
cases, n is already computed just as the size of the dest object, and
nothing is gained. These kinds of problems are solved *much* better by
techniques that allow the compiler or runtime to track the size of
objects and automatically insert checks, which aren't subject to human
error or misuse. The _FORTIFY_SOURCE feature, sanitizers, etc. all
provide much better protection than Annex K functions in this area.

4. The Annex K *printf_s specifications spread FUD about %n being
dangerous, ignoring that this is a poor stand-in for the general
unsafety of *passing a literal string where a format string is
expected* and for use of variable format strings. Without %n, the
impact of such bugs is somewhat reduced, but it's still possible to
get heartbleed-like info leak exploits from them. A real hardened
version of printf-family functions would take a list of argument types
and match the format string against it, and this list would be
generated automatically by the tooling (ala _FORTIFY_SOURCE).

5. Expanding on the topic of FUD/misinformation, both the introduction
of the original *_s functions, and lobbying for their inclusion in the
standard (which eventually reached the compromise of just putting them
in an Annex), was not about improving the C language or making useful
tools for programmers, but about introducing incompatibility and
fragmentation to the language/standard with the goal of undermining
it. The company that introduced it produces a product that is not
compatible with the C language as specified and does not even aim to
be, but aims to give the impression of being a C implementation (it's
mainly a C++ implementation, though likely not conforming to that
standard either). This is part of a long history, including wrong
wchar_t handling, inverting the meaning of %s and %ls with the wide
printf functions, etc. etc. etc. See also point #1 above about
incompatibility of the Annex K functions themselves. It's my position,
and I believe it's shared by many others in the musl community and C
language communities, that parties not interested in implementing or
using the standard should not try to influence its direction, and that
this kind of behavior should not be rewarded by playing along with it,
but that it should be shunned as long as doing so is practical.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.