Usage of Secure C (memcpy_s, strcpy_s etc) functions on OpenSSL

Michael Wojcik Michael.Wojcik at microfocus.com
Wed Nov 27 15:57:04 UTC 2019


> From: Phillip Susi <phill at thesusis.net>
> > Michael Wojcik writes:

> > Some C experts have argued that the length-checking versions of the library functions, either the C90
> > ones such as strncat or the Appendix K ones, are essentially pointless anyway; that the caller needs to
> > handle truncation and so ought to know whether truncation (or overflow) would occur before
> > attempting the operation.

> Isn't this normally/easilly handled simply by passing sizeof( buffer ) -
> 1?  Then the last byte is always \0 whether or not the copy was truncated.

No, for a number of reasons:
- The buffer may be dynamically allocated, in which case sizeof buffer is very much the wrong thing.
- A trailing nul byte is not always desirable (not everything is a string), and not all of the Appendix K
functions will append one. Neither will strncpy, if the limit is reached; strncpy has broken semantics.
- The buffer size (less 1) is the wrong value to pass when using strncat with a destination that does not start
with a nul character. Developers also frequently miss the fact that strncat can append length+1 bytes to
the buffer. (strncat's semantics are dangerously non-obvious.)
- Non-trivial programs *will still have to handle truncation properly*. It's rarely the case for a non-trivial
program that "silently truncate the data" is a good way to handle it. A well-behaved program will treat
truncation as an error or a special case that needs further handling, or at least needs to be flagged to the
user or some other diagnostic sink. The C90 length-checked functions don't communicate truncation to
the caller; the Annex K ones only return "a non-zero value" if a constraint is violated, so there's no
standardization as to how a particular constraint violation is communicated.

Also, sizeof is an operator, not a function. There's no reason to parenthesize its argument unless the
argument is a type name, in which case it's parenthesized as a special syntactic case.

Incidentally, I misremembered; it's Annex K, not Appendix K, and it was introduced in C11, not C99. So the
Annex K functions weren't even standardized until C11, and they're still optional there (though Annex K is
normative).


More information about the openssl-users mailing list