The ups and downs of strlcpy()
Posted Jul 19, 2012 2:25 UTC (Thu) by quotemstr
Parent article: The ups and downs of strlcpy()
Microsoft came much closer to getting these sorts of functions right than the BSD people did. Consider strcpy_s and strncpy_s. strcpy_s's signature looks like this:
const char *strSource
By default, the function checks that we're copying at most (numberOfElements - 1) bytes plus a terminating NULL into strDest. If we try to exceed this buffer, strcpy_s crashes
explicitly with the equivalent of abort(3). This way, we still deflect a potential security hole and turn it into a relatively safe and controlled (if inconvenient) crash, thereby closing some security holes without introducing new truncation-based attacks.
If you do want the truncation behavior, you can use strncpy_s:
const char *strSource,
strncpy_s works just like strncpy, except 1) it has the same buffer-checking safeties as strncpy, 2) always NULL-terminates the destination buffer, aborting if there's not enough room, and 3) doesn't zero-fill the remainder of the buffer if strlen(strSource) < count. This function is useful enough on its own, but you can get strlcpy-like truncation behavior by passing the special value _TRUNCATE for the count parameter. In this case, when the input string is too long, strncpy_s truncates it and instead of aborting, returns the special value STRUNCATE.
By decoupling the output buffer size from the expected number of bytes to copy, we can sidestep a lot of the issues that this article raises for strlcpy. There are also neat C++ template overloads that let you call these functions and have the compiler fill in numberOfElements in the case that you're using C++ and strDestination is an array.
The singular flaw of the entire *_s family of functions is the _set_invalid_parameter_handler function, which allows you to turn off the abort behavior above. There's no good reason to do so, and nobody in practice does, making this family of functions a much better alterantive to strlcpy and friends.
to post comments)