csecuritygccc11tr24731

Why didn't gcc (or glibc) implement _s functions?


_s functions, such as scanf_s, printf_s seems to be optional standard. MSVC has implemented these functions, but gcc hasn't.

Is there specific reason for not implementing secure functions? Is scanf of glibc secure enough?


Solution

  • The _s functions are optional (Annex K of the C11 standard). They're widely regarded as 'not very beneficial'.

    In the answers to my question Do you use the TR-24731 "safe" functions?, you can find information about where there are problems with the standard specification — such as crucial differences between the standard and Microsoft's implementation. TR 24731-1 was a technical report from the C standard committee. The report was incorporated almost verbatim — with an extra, previously omitted, function, memset_s() — in the C11 standard as (optional but 'normative') Annex K. There's also TR 24731-2 for a different set of functions — without the _s suffix. It ran into resistance for a different set of reasons.

    Also, there is a proposal before the C Standard Committee that the functions defined in Annex K should be removed from the next revision of the standard:

    That paper is a straightforward and compelling read of the reasons why the TR-24731 (*_s()) functions have not been widely implemented.

    Key reasons include:

    • The problem is only spotted once, then fixed, and then the *_s() function is unnecessary.
    • This makes it very hard to test the *_s() functions, or the code which uses them.
    • It isn't easy to integrate the new functions into old code (which is where there'd be most benefit).
    • The functions inherently slow down software with extensive but redundant checking.

    See the paper for more details. The paper ends with the section:

    Suggested Technical Corrigendum

    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.


    Annex K was not removed from C17. Two new papers from the standards committee (ISO JTC1/SC22/WG14) discuss Annex K (and are in favour of retaining the functions):


    2023-03-05: It looks as though C23 will retain Annex K as an optional part of the standard. However, there is a new function, memset_explicit(), which does the job that memset_s() does — the optimizer is not allowed to skip the code, even if the variable set is not used again.

    void *memset_explicit(void *s, int c, size_t n);
    

    Description
    2 The memset_explicit function copies the value of c (converted to an unsigned char into each of the first n characters of the object pointed to by s. The purpose of this function is to make sensitive information stored in the object inaccessible380).

    380) The intention is that the memory store is always performed (i.e., never elided), regardless of optimizations. This is in contrast to calls to the memset function (7.26.6.1).