For decades, C and its immediate descendants have been the programming languages of choice for systems programming. In the early 1970s, when C was developed, it was an important step forward from assembly language. Fifty years on, we can do better.
Computer security wasn’t on most people’s radar in 1970, and for many years thereafter. The first major security vulnerability on the internet occurred many years later in 1988. It was known as the internet worm and took advantage of a buffer overflow, where an array in memory was indexed outside its bounds.
In the C language family, which includes C++, arrays are not bounds-checked. It is up to the programmer to ensure the array is accessed correctly. Buffer overflow errors are therefore common. Worse, it is easy to deliberately cause a buffer overflow and thereby access memory that one should not.
Buffer overflow is just one example of memory unsafety. Other related examples include pointer arithmetic and dangling pointers (aka use-after-free bugs). Today, we have many programming languages which employ a variety of techniques to guarantee that any program written in those languages will be free of memory safety issues. The C family of languages make no such guarantee; memory safety was never a design goal of these languages.
About 70% of security vulnerabilities are due to violations of memory safety. This claim is backed up by overwhelming data. Memory safety accounts for:
In July 2022, 5/6 of the vulnerabilities fixed in Chrome 103.0.5060.134 were memory safety issues. Clearly, eliminating memory-safety bugs would be enormously helpful. The industry has known how to do that for many years: use memory safe programming languages. Historically, the problem has always been the associated cost in terms of performance. Due to the importance of memory safety, people have been working on new strategies to achieve it without the traditional overhead. Today we know how to eliminate memory safety errors with little to no runtime cost. Languages, such as Rust, use innovations in type system design to guarantee memory safety without costly runtime support.
This leads to an inescapable conclusion: stop writing new systems code in C/C++ (or more generally, in memory unsafe languages).
This is not a call for massive, indiscriminate rewrites of existing code. Replacing existing software is costly and not without risks. However, the industry must stop aggravating the problem by adding more memory-unsafe code to existing codebases. For existing code, prioritize rewriting the most sensitive components: those that are responsible for validating or consuming untrusted user inputs, those running in a privileged context, those running outside of a sandbox, etc.
This position, though widely held, is still controversial to some. Here are some of the common arguments made in favor of the status quo, and our responses to them.
See Quantifying Memory Unsafety and Reactions to It for a detailed discussion of the above points.
Despite the objections, momentum for the needed changes is growing. Large investments are being made in the Open Source Software Security Foundation (backed by the Linux Foundation) for example. Memory safety has been discussed in US Senate reports and by the NSA. Consumer Reports also works to identify the various incentives that could accelerate this movement by offering a series of recommendations for companies and state agencies.
To summarize:
The importance of computing to society has grown enormously over the past fifty years. The threat landscape to our computing infrastructure has also changed radically over recent decades. However, the programming languages we use to build our computing systems have not changed accordingly. Lack of memory safety is the largest single source of security vulnerabilities in software. This is not peculiar to any specific type of software, as everywhere memory-unsafe languages are in use, memory safety issues abound. And by the numbers, no other class of vulnerability comes close.
We now have the means to address this growing problem and it is crucial that we as an industry do so. Fortunately, recognition of the situation is spreading, but the problem is urgent and there is no time to lose.