Improving Software Security through C Language Standards
This blog post describes my history with the C Standards Committee, the work standards organizations are currently doing in software security, and the future of NCC Group’s work in improving software security by working with the C Standards Committee and other standardzation efforts.
I became involved with the C Standards Committee (more formally, ISO/IEC JTC 1/SC 22/WG 14) while I was writing the first edition of Secure Coding in C and C++. At the time, WG 14 was working on a document called “C Library Security TR 24731,” which was meant to standardize the “_s” functions developed by Microsoft. I found myself talking to Randy Meyers, who was then chair of J11 (which became PL22.11), concerning the odd behavior of the gets_s function, which failed to consume the end-of-line character. He invited me to attend the WG 14 meeting in Lillehammer, Norway, in the spring of 2005, and I have remained involved with the C Standards Committee ever since. At the upcoming meeting of WG14 in Freiburg im Breisgau, Germany NCC Group will obtain voting rights in PL22.11.
The main reason I became involved in C language standardization (and remain involved) is to influence the evolution of the language to enable the development of secure code. Over the past 15 years, we’ve had several major successes:
- Publication of ISO/IEC TS 17961:2013 Information technology — Programming languages, their environments and system software interfaces — C secure coding rules
- Annex K Bounds-checking interfaces (normative)
- Annex L Analyzability (normative)
And a number of minor successes:
- N 1813 2014/03/25 Seacord, Clarifying objects accessed in signal handlers
- N 1617 2012/06/04 Seacord, Missing divide by zero entry in Annex J.2
- N 1339 2008/08/11 Seacord, Extensions to the C1X library to enhance security
There are a relatively small number of international standards organizations that develop standards dealing with Information Technology. A few of the better known organizations are the International Organization for Standardization (ISO), International Electrotechnical Commission (IEC), Institute of Electrical and Electronics Engineers (IEEE), and the Internet Engineering Task Force (IETF).
ISO and IEC formed the joint technical committee JTC1 through which ISO and IEC develop information technology standards; JTC 1’s title is “Information Technology.” JTC1 includes SC 22, which is the international standardization subcommittee for programming languages, their environments and system software interfaces, oftentimes called the “portability subcommittee”.
A 2001 article from the ISO Bulletin magazine by former SC 22 chair John Hill laid out SC 22’s scope as follows:
SC 22’s scope covers a limited set of popular programming languages, some specific formal specification languages, the operating systems POSIX and Linux, and various language bindings. Its standards primarily focus on high level programming environments to improve portability of applications, productivity and mobility of programmers as well as compatibility of applications over time. SC 22’s standards are produced and maintained in response to extensive and diverse market requirements.
SC22 contains the following active working groups:
- WG 04 COBOL
- WG 05 Fortran
- WG 09 Ada
- WG 14 C
- WG 17 Prolog
- WG 21 C++
- WG 23 Programming Language Vulnerabilities
- WG 24 Linux Standard Base (LSB)
At a high level of abstraction the work program of SC 22 (taken from the same 2001 article) has three main goals
- Support the current, massive, global investment in software applications by maintenance and improvement of standardized programming languages
- Continuously improve programming environment standardization through the documentation and application of forty years of lessons learned in the specification of these standards
- Respond to emerging technological opportunities such as network applications and global development practices
SC 27 is another subcommittee in ISO/IEC JTC 1 that focuses on information security, cybersecurity and privacy protection. The scope of SC 27 from their website is the development of standards for the protection of information and information and communications technology (ICT). This includes generic methods, techniques and guidelines to address both security and privacy aspects, such as:
- Security requirements capture methodology;
- Management of information and ICT security; in particular information security management systems, security processes, and security controls and services;
- Cryptographic and other security mechanisms, including but not limited to mechanisms for protecting the accountability, availability, integrity and confidentiality of information;
- Security management support documentation including terminology, guidelines as well as procedures for the registration of security components;
- Security aspects of identity management, biometrics and privacy;
- Conformance assessment, accreditation and auditing requirements in the area of information security management systems;
- Security evaluation criteria and methodology.
ISO members are the foremost national standards bodies in their countries; there is one member per country. Individuals or companies cannot become ISO members, but can participate as an expert at working group meetings by becoming a member of a participating national body. The US national body is ANSI (which subcontracts many of its administrative functions within JTC 1 to INCITS), Germany is DIN, and the UK is BSI.
NCC Group is a participating member of INCTIS Task Group PL22.11, Programming Language C, is responsible for the technical development of the standard for C programming language. This technical committee is the U.S. Technical Advisory Group to ISO/IEC JTC 1/SC 22/WG 14.
Improving software security is a daunting task, and to have any real hope of reducing the overall number of software vulnerabilities each year it is necessary to find a solution that scales. Most of the critical infrastructure around the world is written in C, including networking software, Industrial Control Systems (ICS), SCADA as well as embedded software in IoT devices, automobiles, and other transportation. There are also valid reasons to improve security in other domains, but the risks of not securing critical infrastructure are the most profound. So how do we improve the security and decrease vulnerabilities across all these systems?
One thing that can be done is to publish information on how to code securely in C and C++, build a tool to search for vulnerabilities (of which there are already many), build a compiler specific extension or secure library, or develop a process for building secure systems. All of these are good ideas. Having made contributions in all these areas, however, I appreciate how difficult it can be to get these ideas adopted in practice. Developing security processes and building tools to search for vulnerabilities are useful, but unfortunately, just because they exist doesn’t mean developers will use them. The compiler is guaranteed to be used because not many programmers want to generate their binaries by hand. However, there are over 200 compilers in the C ecosystem, so building an extension for one compiler only helps improve the security of code developing using that compiler, and only if that extension is used. So this is where standardization can help amplify the solution. Once a new security improvement is adopted by the C Standard, compiler implementers are more likely to implement and deploy the feature so that it can be broadly deployed as there is always a customer pull to support new features of the standard. Inclusion in the standard does not ensure adoption, as the extent and rate to which new features are adopted various significantly. For starters, not all compilers implement everything in the standard. Security annexes such as “Annex K Bounds-checking interfaces” and “Annex L Analyzability” are optional meaning that compilers do not need to implement them, and if compilers don’t choose to implement them, they may not remain in the standard forever.
With respect to adoption, not all implementations support all the features of the C Standard. There are two forms of conforming implementations: hosted and freestanding. A conforming hosted implementation must accept any strictly conforming program. A conforming freestanding implementation need only accept any strictly conforming program in which the use of the library features is confined to the contents of the standard headers
<stdnoreturn.h>. Consequently, a change to a library feature not listed above need not be made to freestanding implementation.
The next problem is the speed with which compiler implementers adopt new versions of the standard. GCC and Clang are both fairly aggressive in trying to keep up to date with the latest version of the C Standard. Many embedded C compilers still implement the C89/C90 standards which are now over 30 years old. These compiler vendors haven’t felt the need to update or sufficient pressure from their user communities to support newer versions of the standards. Visual Studio does not fully support C99 and at the time of writing there are no plans to do so.
Finally, standardization is not a fast process. WG14 has released four versions of the C Standard in the past 30 years, and even that number is misleadingly high as C17 is really just C11 with some defects repaired. WG14 is currently working on the next major release of the standard C2X so now is a great time to get involved in C Standardization because it is possible to introduce new features to the language and not just repair defects. The standardization process is intentionally slow, because the world runs on C code (as previously noted) and no one on the committee wants to break the world.
With all the difficulties, standardization is still the best way to widely deploy security features that benefit a broad community and have the potential to result in a measurable decrease in the overall number of vulnerabilities deployed each year. At the upcoming standards meeting in March in Germany, I’ll be presenting the following papers:
- N 2465 2020/02/10 intmax_t, a way forward
- N 2464 2019/12/01 Seacord, Zero-size Reallocations are Undefined Behavior
There will also be other interesting papers related to security presented at this meeting including one from my old Secure Coding team at CERT:
- N 2466 2020/02/09 Svoboda, Towards Integer Safety
- N 2477 2020/02/04 Alepins, Const functions
- all the others