Today’s computer systems are distressingly insecure. As such, the foundation upon which our information-based society is built is under constant threat, making everyone vulnerable to attacks. The causes for this dissatisfying state of affairs are complex, but at this point mostly historical: our programming languages, compilers, runtime systems, and architectures were designed in an era of scarce resources and they far too often trade security for efficiency or compatibility. In this post we discuss a promising line of research, which we call secure compilation, that aims to address this historical imbalance.

Programming Languages and Security

Mainstream low-level languages like C and C++ give up even on the most basic safety guarantees for the sake of efficiency. The lack of memory safety in these languages leaves programmers bearing the burden for security: the smallest mistake in widely-deployed C and C++ code can cause security vulnerabilities with disastrous consequences. Over the past 12 years, around 70% of all patched security vulnerabilities at Microsoft were memory safety issues. The C and C++ languages do not guarantee memory safety and their compilation chains do not enforce it because deployed hardware provides no good support for it and software checks could incur high overhead, e.g., 70-80% in SoftBoundCETS. Instead, much weaker, low-overhead mitigation techniques are deployed today, but they are routinely circumvented by practical attacks. Worse, just ensuring memory safety would not be enough to make C and C++ safe, as the standards for these languages call out a much larger number of undefined behaviors, for many of which compilers produce code that behaves arbitrarily. This includes for instance invalid unchecked type casts and integer overflows, which often also lead to security vulnerabilities.

Safe(r) Programming Languages

Languages such as Java, C#, ML, Haskell, and Rust are safer, providing type and memory safety by default as well as many useful abstractions for writing secure software (e.g., safe memory management, modules, and interfaces). These languages are an important step forward, but are still not immune to low-level attacks. For a start, these languages often provide unsafe escape hatches (e.g., unsafe blocks in Rust, Obj.magic in OCaml, and performUnsafeIO in Haskell). Moreover, the run-time systems for these languages are large, complex, and often written in C and C++, which makes them a target of attacks. Finally, all the safety guarantees of the source language are lost when interacting with low-level code, for instance via linked native libraries. So even if a critical program is secure with respect to the semantics of a high-level language, any mistake in the unsafe parts of the code, run-time system, or linked low-level code can break its security.

Beyond Safety

Other problems arise because today’s mainstream languages provide no way to specify the intended security properties, such as data confidentiality. For instance, for cryptographic implementations it is crucial that the running time of the computation does not depend on the value of secret keys, otherwise side-channel attacks can be used to infer the keys. However, even if one manages to achieve such a secret independence property in the source language, an unaware compilation chain is likely to break the property when compiling the code. In fact, producing machine code for modern architectures that can withstand powerful side-channel is a challenging open problem. All software implicitly trusts the abstractions of the hardware, and hardware bugs and loosely specified software-hardware interfaces can enable powerful side-channels (e.g., Spectre, Meltdown, ZombieLoad, Fallout, RIDL, or SMoTherSpectre) and can even result in violations of memory safety.

Towards Secure Compilation

Secure compilation is an emerging field that puts together advances in programming languages, security, compilers, systems, formal verification, and hardware architectures. Secure compilation aims to devise compilation chains that eliminate many of the security attacks above, and that allow sound reasoning about security properties in the source language. In particular, the secure compilation field targets:

Community

Programming languages research can play a big role in secure compilation. A strong community is quickly crystallizing around the workshop on Principles of Secure Compilation (PriSC), organized every year together with POPL since January 2017. PriSC is an informal 1-day workshop without proceedings offering a forum for presenting and discussing recent and ongoing work. The previous PriSC edition organized with POPL 2019 in Cascais, Portugal brought together 54 participants, mostly PL researchers and enthusiasts, but also members of the security and systems communities with an interest in secure compilation. The next PriSC edition will happen with POPL 2020 in New Orleans.

In addition, a new Dagstuhl seminar series (2018, 2020) aims to identify interesting research directions as well as open challenges and to bring together the various communities interested in secure compilation. The secure compilation community includes, for instance, researchers building secure compilation chains, designing security enforcement and attack-mitigation mechanisms in both software and hardware, and developing formal verification techniques for secure compilation.

Catalin Hritcu is a researcher at Inria Paris, where he works on security foundations and formal verification. He was awarded an ERC Starting Grant on formally secure compilation and is also involved in the design of the F* verification system.

David Chisnall is a researcher at Microsoft Research in Cambridge, UK. He is a developer of the CHERI capability machine, a former member of the FreeBSD Core Team, the maintainer of the GNUstep Objective-C runtime, and a long-time contributor to the LLVM project.

Deepak Garg is a tenured faculty member at the Max Planck Institute for Software Systems (MPI-SWS) in Kaiserslautern and Saarbrücken, Germany. He is broadly interested in security, programming languages, formal logic, and systems.

Mathias Payer is a security researcher and assistant professor at EPFL in Switzerland, leading the HexHive laboratory. His research focuses on protecting applications in the presence of vulnerabilities, with a focus on memory corruption and type violations.

Disclaimer: These posts are written by individual contributors to share their thoughts on the SIGPLAN blog for the benefit of the community. Any views or opinions represented in this blog are personal, belong solely to the blog author and do not represent those of ACM SIGPLAN or its parent organization, ACM.