The declaration of strtok_s
in C11, and its usage, look to be very different from the strtok_s
in compilers like the latest bundled with Visual Studio 2022 (17.4.4) and also GCC 12.2.0 (looking at MinGW64 distribution).
I fear the different form has been developed as a safer and accepted alternative to strtok
long before C11. What happens now if someone wants to use strtok_s
and stay C11 compliant?
Are the compiler supplied libraries C11 compliant?
Maybe it's just that I've been fooled by something otherwise obvious, and someone can help me...
This is C11 (and similar is to C17 and early drafts of C23):
char *strtok_s(char * restrict s1,
rsize_t * restrict s1max,
const char * restrict s2,
char ** restrict ptr);
the same can be found as a good reference in the safec library
While MSC/VC and GCC have the form
char* strtok_s(
char* str,
const char* delimiters,
char** context
);
CodePudding user response:
The C11 "Annex K bounds checking interfaces" was received with a lot of scepticism and in practice nearly no standard lib implemented it. See for example Field Experience With Annex K — Bounds Checking Interfaces.
As for the MSVC compiler, it doesn't conform to any C standard and never made such claims - you can try this out to check if you are using such a compiler or not:
#if !defined(__STDC__) || (__STDC__==0)
#error This compiler is non-conforming.
#endif
In particular, MSVC did not implement Annex K either, but already had non-standard library extensions in place prior to C11.
In practice _s
means:
- Possibly more safe or possibly less safe, depending on use and what the programmer expected.
- Non-portable.
- Possibly non-conforming.
If portability and standard conformance are important, then avoid _s
functions.
In practice _s
functions protect against two things: getting passed non-sanitized input or null pointers. So assuming that you do proper input sanitation and don't pass null pointers to library functions, the _s
functions aren't giving you extra safety, just extra execution bloat and portability problems.
CodePudding user response:
What happens now if someone wants to use
strtok_s
and stay C11 compliant?
You de facto can't.
And it's not limited to just strtok_s()
. The entire C11 Annex K set of implementations is fractured, and because the major deviations from the standard are from Microsoft's implementation, there will probably never be a way to write portable, standard-conforming code using the Annex K functions.
Per N1967 Field Experience With Annex K — Bounds Checking Interface:
Available Implementations
Despite the specification of the APIs having been around for over a decade only a handful of implementations exist with varying degrees of completeness and conformance. The following is a survey of implementations that are known to exist and their status.
While two of the implementations below are available in portable source code form as Open Source projects, none of the popular Open Source distribution such as BSD or Linux has chosen to make either available to their users. At least one (GNU C Library) has repeatedly rejected proposals for inclusion for some of the same reasons as those noted by the Austin Group in their initial review of TR 24731-1 N1106]. It appears unlikely that the APIs will be provided by future versions of these distributions.
Microsoft Visual Studio
Microsoft Visual Studio implements an early version of the APIs. However, the implementation is incomplete and conforms neither to C11 nor to the original TR 24731-1. For example, it doesn't provide the
set_constraint_handler_s
function but instead defines a_invalid_parameter_handler _set_invalid_parameter_handler(_invalid_parameter_handler)
function with similar behavior but a slightly different and incompatible signature. It also doesn't define theabort_handler_s
andignore_handler_s
functions, thememset_s
function (which isn't part of the TR), or theRSIZE_MAX
macro. The Microsoft implementation also doesn't treat overlapping source and destination sequences as runtime-constraint violations and instead has undefined behavior in such cases.As a result of the numerous deviations from the specification the Microsoft implementation cannot be considered conforming or portable.
...
Safe C Library
Safe C Library [SafeC] is a fairly efficient and portable but unfortunately very incomplete implementation of Annex K with support for the string manipulation subset of functions declared in
<string.h>
.Due to its lack of support for Annex K facilities beyond the
<string.h>
functions the Safe C Library cannot be considered a conforming implementation.
Even the Safe C library is non-conforming.
Whether these functions are "safer" is debatable. Read the entire document.
Unnecessary Uses
A widespread fallacy originated by Microsoft's deprecation of the standard functions in an effort to increase the adoption of the APIs is that every call to the standard functions is necessarily unsafe and should be replaced by one to the "safer" API. As a result, security-minded teams sometimes naively embark on months-long projects rewriting their working code and dutifully replacing all instances of the "deprecated" functions with the corresponding APIs. This not only leads to unnecessary churn and raises the risk of injecting new bugs into correct code, it also makes the rewritten code less efficient.
Also, read the updated N1969 Updated Field Experience With Annex K — Bounds Checking Interfaces:
Despite more than a decade since the original proposal and nearly ten years since the ratification of ISO/IEC TR 24731-1:2007, and almost five years since the introduction of the Bounds checking interfaces into the C standard, no viable conforming implementations has emerged. The APIs continue to be controversial and requests for implementation continue to be rejected by implementers.
The design of the Bounds checking interfaces, though well-intentioned, suffers from far too many problems to correct. Using the APIs has been seen to lead to worse quality, less secure software than relying on established approaches or modern technologies. More effective and less intrusive approaches have become commonplace and are often preferred by users and security experts alike.
Therefore, we propose that Annex K be either removed from the next revision of the C standard, or deprecated and then removed.