Programming languages: How Google is improving C++ memory safety

Google's Chrome is looking to bring memory safety to Chrome's C++ codebase.
Written by Liam Tung, Contributing Writer

Google's Chrome team is looking at heap scanning to reduce memory-related security flaws in Chrome's C++ codebase, but the technique creates a toll on memory – except when newer Arm hardware is used.   

Google can't just rip and replace Chromium's existing C++ code with memory safer Rust, but it is working on ways to improve the memory safety of C++ by scanning heap allocated memory. The catch is that it's expensive on memory and for now only experimental.

Google and Microsoft are major users of and contributors to the fast programming language C++, which is used in projects like  Chromium, Windows, the Linux kernel, and Android. There is growing interest in using Rust because of its memory safety guarantees.

SEE: Working hard or hardly working? Employees don't trust their colleagues to be productive while working from home

But switching wholesale from C++ in Chrome to a language like Rust simply can't happen in the near term. 

"While there is appetite for different languages than C++ with stronger memory safety guarantees, large codebases such as Chromium will use C++ for the foreseeable future," explain Anton Bikineev, Michael Lippautz and Hannes Payer of Chrome's security team.   

Given this status, Chrome engineers have found ways to make C++ safer to reduce memory-related security flaws such as buffer overflow and use-after free (UAF), which account for 70% of all software security flaws. 

C++ doesn't guarantee that memory is always accessed with the latest information of its structure. So, Google's Chrome team have been exploring the use of a "memory quarantine" and heap scanning to stop the reuse of memory that is still reachable. 

UAFs make up the majority of high-severity issues affecting the browser. A case in point is this week's Chrome 102, which fixed one critical UAF, while six of eight high-severity flaws were UAFs.

UAF access in heap allocated memory is caused by "dangling pointers", which occurs when memory used by an application is returned to the underlying system but the pointer points to an out-of-date object. Access through the dangling pointer results in a UAF, which is hard to spot in large code bases.

To detect UAFs, Google already uses C++ smart pointers like MiraclePtr, which also caused a performance hit, as well as static analysis in compilers, C++ sanitizers, code fuzzers, and a garbage collector called Oilpan. The appeal of Rust is that its compiler spots pointer mistakes before the code runs on a device, thus avoiding performance penalties. 

Heap scanning may add to this arsenal if it makes it beyond experimental phase, but adoption will depend on devices using the latest Arm hardware. 

Google explains how quarantines and heap scanning works: "The main idea behind assuring temporal safety with quarantining and heap scanning is to avoid reusing memory until it has been proven that there are no more (dangling) pointers referring to it. To avoid changing C++ user code or its semantics, the memory allocator providing new and delete is intercepted. 

Upon invoking delete, the memory is actually put in a quarantine, where it is unavailable for being reused for subsequent new calls by the application, Google said. "At some point a heap scan is triggered, which scans the whole heap, much like a garbage collector, to find references to quarantined memory blocks. Blocks that have no incoming references from the regular application memory are transferred back to the allocator where they can be reused for subsequent allocations."

Google's heap scanning consists of a set of algorithms it calls StarScan (*Scan). But one version of *Scan caused a memory regressions of 8% in Speedometer2 browser performance benchmark tests. *Scan in the render process regressed memory consumption by about 12%, Google notes. 

Google then tried hardware-assisted memory tagging via the relatively memory tagging extension (MTE) in ARM v8.5A to reduce performance overheads. 

SEE: Developers are burned out. Here's what they're doing to tackle it

The *Scan with MTE benchmark results were promising. After re-doing the *Scan experiments on top of MTE in the renderer process, memory regression was about 2% in Speedometer2. 

"The experiment also shows that adding *Scan on top of MTE comes without measurable cost," they wrote. 

But for now, undertaking heap scanning in a way that doesn't create an unacceptable performance hit remains a thing for the future, when MTE is more widely adopted. 

"C++ allows for writing high-performance applications but this comes at a price, security. Hardware memory tagging may fix some security pitfalls of C++, while still allowing high performance," Chrome security team's conclude.  

"We are looking forward to see a more broad adoption of hardware memory tagging in the future and suggest using *Scan on top of hardware memory tagging to fix temporary memory safety for C++. Both the used MTE hardware and the implementation of *Scan are prototypes and we expect that there is still room for performance optimizations." 

Editorial standards