Document: N1112 Date: 2005/03/21 ISO/IEC JTC 1/SC22 Programming languages, their environments and system software interfaces Secretariat: U.S.A. (ANSI) ISO/IEC JTC 1/SC22 N3880 TITLE: Summary of Voting on SC 22 N 3838, Registration for WDTR 24731-Information technology-Programming languages, their environments and system software interfaces-Specification for Secure C Library Functions DATE ASSIGNED: 2005-03-16 SOURCE: SC 22 Secretariat BACKWARD POINTER: N/A DOCUMENT TYPE: Summary of Voting PROJECT NUMBER: 22.24731 STATUS: The results of this ballot are forwarded to SC 22/WG 14 for review, production of a disposition of comments report, and preparation of the DTR text. The comments of the United Kingdom can be found at: ACTION IDENTIFIER: ACT DUE DATE: N/A DISTRIBUTION: Text CROSS REFERENCE: SC 22 N3838 DISTRIBUTION FORM: Def Sally Seitz ANSI 25 West 43rd Street New York, NY 10036 Telephone: (212) 642-4918 Fax: (212) 840-2298 Email: sseitz@ansi.org _____end of cover page, beginning of PDTR registration summary______________ SUMMARY OF VOTING ON Letter Ballot Reference No: SC22 N3838 Circulated by: JTC 1/SC22 Circulation Date: 2004-12-14 Closing Date: 2005-03-14 SUBJECT: Summary of Voting on SC 22 N 3838, Registration for WDTR 24731-Information technology-Programming languages, their environments and system software interfaces-Specification for Secure C Library Functions The following responses have been received on the subject of registration: "P" Members supporting registration without comments 6(Czech Republic, Denmark, Finland, France, Italy, Republic of Korea) P" Members supporting registration with comments 3 (Germany, Netherlands, United States) "P" Members not supporting registration 2(Canada, Japan) "P" Members abstaining 2 (Switzerland, United Kingdom) "P" Members not voting 7 (Belgium, China, Egypt, DPR of Korea, Romania, Russian Federation, Slovenia, Ukraine) National Body Comments Canada Comments on WDTR 24731 "Specification of Secure C Library Functions" Canada does not agree with the use of the word "secure" in the title of this document. This word carries considerable baggage for the safety and security communities and implies functionality that is not provided. We would suggest alternative terminology, such as "bounded". Some of the functions provided exist or conflict with functions provided in other domains, such as POSIX or SUS. If the behaviour is different than these specifications, then programs that attempt to use them may be incorrect. Even if the behaviour is the same, then the pre-existing specification must be respected. Examples of such functions are: strtok_r, strcpy_s and strcat_s. In particular, strcpy_s provides identical functionality to strlcpy which has been in use for some time. Special mention is required of strerror_s. A mechanism is required to predetermine the size of the string to be returned so that the buffer can be preallocated. Special mention is also made or "rand". Saying that cryptography methods must be used is insufficient. The function specification ignores several issues, such as blocking, enthropy and seeding of such functions. Special mention is made of strtok_r. This function should clearly state that any string to be read by such a function may already be effectively unbounded, and while it may be bounded by the buffer in strtok_s, the effects of inputting the original unbounded string may already have occured. Germany German Comment on document ISO/IEC JTC 1/SC 22 N3838 ISO/IEC WDTR 24731 Information technology-Programming languages, their environments and system software interfaces-Specification for Secure C Library Functions: 1) sprintf_s and other read functions with the exception of strnlen need to be addressed somehow. 2) it is worth to consider, whether strncpy_s and strncat_s variants with one parameter for length should be added. Zero-termination is in that case assumed. 3) it is worth to consider offering a feature, simply aborting the program upon buffer length overrun. Such an option could be activated conditionally via #pragma or #define. (End of comment) Japan As already described in our comment on NWIP ballot, we think it is extremely hard to make the C programming language secure by just adding a set of new functions leaving the existing insecure ones untouched. To make the C programming language truly secure it is necessary to abolish the existing insecure features like pointer operations and some dangerous functions. We strongly request WG14 to produce the rationale or annex which clearly states the following points: 1) Clearly state the policy and criteria for introduction of new functions For example, we think that gets_s() is redundant and should be eliminated from the TR because the functionality of gets_s() can be covered by existing fgets() function. So, please make clear the reason of adding gets_s() besides fgets(). 2) Clearly and concretely state what kinds of security hole exist in the current ISO C standard(syntax and libraries). 3) Clearly explain what kind of vulnerability is fixed for each proposed function one-by-one. For example, we cannot understand what is improved in wctomb_s() from the original wctomb(). Please provide the explanation of the advantage of wctomb_s() over wctomb(). 4) Give the guide for secure programming by using the proposed functions. Netherlands The Netherlands votes 'yes' on the Registration of WDTR 24731 with the following comments: 1 - Section 3.1, the definition of the term 'diagnosed undefined behavior' is unclear; change to behavior, that is invoked by the use of a nonportable or erroneous program construct or of erroneous data,and that an implementation shall diagnose by, in effect, calling an implementation-defined function. 2 - Section 5.3, para 2; replace 2nd sentence by If a function that has parameters of type rsize_t is called with values for those parameters that are greater than RSIZE_MAX the behaviour shall be diagnosed undefined behaviour. 3 - Section 5.3, para 4, last sentence: replace 'diagnosable' by 'diagnosed'. 4 - Section 5.5.2.1, para 5, first sentence: replace 'diagnosable' by 'diagnosed'. United States Set 1: 1. WG14/N1089 is a good start on a rationale. There should be one, either included in the TR or in a separate document. 2. The rationale should discuss why there are not _s versions of the following functions, and the general philosophy involving minimizing performance impact. strchr, strcspn, strpbrk, strrchr, strspn, strstr 3. The following functions are missing the specification that they open a file for exclusive access. tmpfile_s, fopen_s, freopen_s 4. From the editor's report, it appears that sprintf_s and snprintf_s will do essentially if not exactly the same thing. Maybe only one of them is needed. 5. It would be best for the committee to spend some more time discussing the notion of diagnosed undefined behavior. This is a new invention for the C standard. ########## Set 2: Page numbers refer to within the document, not the PDF page number. Page v: End of paragraph 6: Extra(?) "*". Page 1: Should ISO/IEC 9899:1999/Cor 2:2004 be added to list of references? Page 7+: Consider changing "bug" to "programming error". Page 7: Footnote 9: Consider changing "constant expression" to "integer constant expression". Page 13: Paragraph 7 / Example 2: The end of that example says: "No assignment to /s/ occurs.". Where is that requirement in normative text? Also, this seems like a large burden to place on the implementation (requires a temporary buffer to hold the input string until that string's length is known). Better would be s[0] is set to a null character, and the other elements of /s/ are unspecified. Page 14/15: Footnote 13: Is on wrong page and overlays the section number. Can the same footnote be referenced by three different sections (which are on different pages)? Page 16: 5.4.4.1p4: Consider adding: "and the other elements of /s/ are unspecified". Page 17: 5.5.1.1p2: Consider adding: "maxsize == 0" to the list of diagnosed undefined behavior. Page 20: 5.5.2.2: Why does qsort_s return void instead of errno_t? How does it indicate failure? Page 24: 5.6.1.2: End of paragraph 3: Extra(?) "*". Page 28: 5.6.2.2p4: The 'm' in 'm+n' should be italic. Page 31: 5.6.4.1p5: Why are there three '.' characters used to overwrite the end of the string (Answer could go in a footnote)? Would it be useful to show some examples both with and without the overwrite? Page 33: 5.7.2.1p2: Is the broken down time before or after the 1900 has been added to it? Why 0 rather than -999 (which fits in a 4 digit field)? Page 37: 5.8.1.1: What happens if the string is longer than the space to store it? Is the first character set to null character? Page 38: Footnote 28 extends too far down the page. Pages 39-40: Footnote 29 is referenced from two pages. Page 46: 5.8.2.2.2p4: The 'm' in '-m+n' should be italic. ########## Set 3: 1. The TR leaves it up to the implementation to determine the value of RSIZE_MAX. The most useful value will often depend on both the implementation and the application, so many/most implementations will provide a way for an application to specify the value (at run-time). On the other hand, some implementations may choose to make the value an unalterable translation-time constant. We would like to see a specified means to set the value of RSIZE_MAX, with a status return indicating whether or not the value was successfully set. One thought might be to do this through a function-like macro in stdint.h, e.g. "errno_t SET_RSIZE_MAX(size_t)". An implementation that did not support an application's setting the value at run-time would not define the macro. Otherwise, an invocation of the macro would return zero if the value was successfully set, or a non-zero value to indicate failure (e.g. an inappropriate value was specified or the application was built in a way to disallow run-time modification of the value). 2. The definition of diagnosed undefined behavior as calling an implementation defined function might benefit from examples of the name ans signature of such a function - not as a requirement, simply to encourage more than one implementation to make the same choices. 3. The memcpy_s function does not list overlap between input and output among its diagnosed undefined behaviors. Is that solely because the language does not define pointer comparison between distinct objects, or is it considered a practical difficulty for real implementations? In fact, the wording of "take on unspecified values", seems to preclude overlap from being diagnosed. That's puzzling, as diagnosing memcpy calls that ought to be memmove calls is certainly a useful capability. ########## Set 4: 1. In some cases there seems to be change for the sake of it from what is either already standard or defacto standard. The common change seems to be return values that were char* with error being NULL being changed to this new errno_t type which is really just an int. strcpy_s strlcpy strcat_s strlcat asctime_s asctime_r gtime_s gtime_r localtime_s localtime_r 2. For many of the functions defined in this TR, it appears that very similar or identical alternatives are already available. In those cases, I'm not sure it makes sense to ignore prior art by defining new replacements. Some examples: A. tmpfile_s() is identical to the existing tmpfile() except for the style of returning the resulting FILE *. B. tmpnam_s() is almost the same as the existing tmpnam_r() except it includes an argument for the size of the destination buffer. More important, however, is the fact that it is still unsafe due to race conditions with others who might create the same files. Safe usage requires the use of tmpfile() or mkstemp() instead. C. strcpy_s() is equivalent to strlcpy(). It seems like providing yet another safe version of strcpy() would be confusing at best. D. fscanf_s() and related variants are just like the current routines except they require a size parameter for buffers that hold the result of %c, %s, and %[ formats. That's very useful, but I believe this feature could be added to the existing scanf() family in a compatible way. What's needed is a format modifier to indicate that the size is specified by a parameter, like the * in printf() format strings. Since scanf() already uses * for assignment suppression, a different character would be needed, but one could choose any unused format character and remain compatible with the existing scanf() functions. 3. A comprehensive Rationale for the TR should be provided. 4. The issues (including missing features) raised in the Secure TR Editor's Report, SC22 WG14 N1089, should be addressed. N1089 is available at http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1089.pdf 5. The committee should consider adding the following functions described in N1089: fprintf_s, printf_s, snprintf_s, sprintf, vfprintf_s, vprintf_s, vsnprintf_s, vsprintf_s, fwprintf_s, swprintf_s, vfwprintf_s, vwprintf_s, wprintf_s, vswprintf_s, mbstowcs_s, wcstombs_s, mbsrtowcs_s, wcsrtombs_s, wcrtomb_s 6. The committee should consider adding support for optional truncation during string copy. See _TRUNCATE in N1089. 7. A footnote should be added explaining that the tmpfile_s, fopen_s, and freopen_s functions should open their files in a "safe" mode giving exclusive (non-shared) access. 8. The committee should carefully consider the issues around "diagnosed undefined behavior," including: A. the name of the term B. the model of behavior C. where the description of diagnosed undefined behavior should appear in a subclause specifying a function (in the "Description" section, in the "Returns" section, or in a new section labeled "Diagnosed Undefined Behavior").