Code Pointer Integrity

Frank Wang
MIT Security Seminar
3 min readDec 27, 2014

Volodymyr Kuznetsov from EPFL came to MIT last week to give a talk at security seminar. This talk was also presented a couple days ago at the biggest systems conference of the year, OSDI. His talk is titled “Code Pointer Integrity.” There is also a paper with more details.

His motivation for his project are control-flow hijack attacks. They have been known for over 50 years. However, the number of CVEs for them have only been increasing. There have been many solutions in the research literature, but it’s usually a tradeoff between security/safety and flexibility/performance. However, his system guarantees safety AND flexibility/performance.

Graph of Control-Flow Hijack CVEs over the last few years

He has two types of protection: practical protection (lower overhead) and guaranteed protection (higher overhead). For practical protection, he guarantees that an attacker cannot forge a code pointer. He does this with instruction level isolation. He has “safe memory” with a safe heap and stack for code pointers where accesses are safe, and all non-code-pointer data is in regular memory, which contains a regular heap and stack as well as read-only code where accesses are fast. For more details, I refer you to the paper.

However, practical protection might cover most situations. It is not precise. A precise solution protects all sensitive pointers, which are code pointers and pointers used to access sensitive pointers. In order to capture these pointers, he uses an over-approximate type-based static analysis: is_sensitive(v) = is_sensitive_type(type of v). In SPEC2006, less than 6.5 percent of memory accesses are sensitive. He has the same layout as the practical protection except his safe memory contains sensitive pointers and metadata instead of just code pointers. His guarantee is that guaranteed memory safety for all sensitive pointers leads to guaranteed protection against control-flow hijack attacks enabled by memory bugs.

The high level idea is that accessing sensitive pointers is safe and accessing regular data is fast. He has a correctness proof for the guaranteed protection, and both types of security prevent attacks from RIPE, which is an intrusion prevention evaluator.

They have a LLVM-based prototype, and plan to integrate upstream into LLVM. They implement this as a flag that can be included in the compilation process (cc -fcpi foo.c). The practical protection only introduces 0.5–1.9 percent overhead for their test cases, and the guaranteed protection only introduces 8.4–10.5 percent overhead. I refer you to the paper for details results. His key insight is memory safety for sensitive data only.

I think that this work solves an important problem, especially given the recent research papers on ROP (return oriented programming) attacks, and this is one of many steps to getting better memory safety for C programs.

--

--

Frank Wang
MIT Security Seminar

Investor at Dell Technologies Capital, MIT Ph.D in computer security and Stanford undergrad, @cybersecfactory founder, former @roughdraftvc