This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implement C11 annex K?

On Tue, Aug 12, 2014 at 05:46:01PM -0400, David A. Wheeler wrote:
> Annex K is extremely useful. Many people want to prevent easy buffer
> overflows and other similar problems.
> E.g., the strcpy function does not check buffer lengths at all,
> while strncpy is badly broken because it zeros out the entire
> destination. None of the standard functions provide a simple "copy a
> string, always terminate, don't go beyond the buffer, and do not do
> unnecessary copues". This is a basic omission in the library, one
> that keeps getting recreated. The current library is missing several
> really basic functionalities. Time to fix it.

Annex K has plenty of fundamental flaws that make it essentially
useless for this purpose. The main problem is the way "runtime
constraint handling" is done. I'll first quote the relevant text:

K.3.1.4 Runtime-constraint violations

"Implementations shall verify that the runtime-constraints for a
function are not violated by the program. If a runtime-constraint is
violated, the implementation shall call the currently registered
runtime-constraint handler (see set_constraint_handler_s in
<stdlib.h>). Multiple runtime-constraint violations in the same call
to a library function result in only one call to the
runtime-constraint handler. It is unspecified which one of the
multiple runtime-constraint violations cause the handler to be


"The runtime-constraint handler might not return. If the handler does
return, the library function whose runtime-constraint was violated
shall return some indication of failure as given by the returns
section in the function's specification."

K. The set_constraint_handler_s function

"The implementation has a default constraint handler that is used if
no calls to the set_constraint_handler_s function have been made. The
behavior of the default handler is implementation-defined, and it may
cause the program to exit or abort."

The important things to take away from this are:

1. Since the default constraint handler is implementation-defined,
   portable code cannot rely on the default handler to catch dangerous
   conditions, nor can it rely on the default handler to return an
   error status to the caller in a way that the caller can handle.

2. The constraint handler is global state, so it cannot be set on a
   per-caller basis. This means, in my terminology, any code using the
   Annex K functions is non-library-safe: it's forced either to modify
   global state in a way that can't safely cooperate with a caller (or
   other library code, much less other threads) that uses the same
   state, or to risk crashing the calling program (via a potential
   default handler that does so).

Basically, this is a backwards, global-state-driven design from the
80s or early 90s that can't be used in modern library-safe,
thread-safe code.

As for your specific example, which I assume is strncpy_s, the
standard function which already solves this problem without the
additonal confusing and error-prone size arguments is snprintf:
snprintf(dest, destsize, "%s", source). And the nonstandard but widely
available function that's even more convenient is strlcpy. And the
name strncpy_s is horribly misleading since its behavior has nothing
to do with strncpy (which is for working with fixed-size, non-C-string
fields, not bounded copying).


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]