Enabling Hardware-enforced Stack Protection (cetcompat) in Chrome

Chrome 90 for Windows adopts Hardware-enforced Stack Protection, a mitigation technology to make the exploitation of security bugs more difficult for attackers. This is supported by Windows 20H1 (December Update) or later, running on processors with Control-flow Enforcement Technology (CET) such as Intel 11th Gen or AMD Zen 3 CPUs. With this mitigation the processor maintains a new, protected, stack of valid return addresses (a shadow stack). This improves security by making exploits more difficult to write. However, it may affect stability if software that loads itself into Chrome is not compatible with the mitigation. Below we describe some exploitation techniques that are mitigated by stack protection, discuss its limitations and what we will do next to approach them. Finally, we provide some quick tips for other software authors as they enable /cetcompat for their Windows applications.

Stack Protection

Imagine a simple use-after-free (UAF) bug where an attacker can induce a program to call a pointer of their choosing. Here the attacker controls an object which occupies space formerly used by another object, which the program erroneously continues to use. The attacker sets a field in this region that is used as a function call to the address of code the attacker would like to execute. Years ago an attacker could simply write their shellcode to a known location, then, in their overwrite, set the instruction pointer to this shellcode. In time, Data Execution Prevention was added to prevent stacks or heaps from being executable.

In response, attackers invented Return Oriented Programming (ROP). Here, attackers take advantage of the process’s own code, as that must be executable. With control of the stack (either to write values there, or by changing the stack pointer) and control of the instruction pointer, an attacker can use the `ret` instruction to jump to a different, useful, piece of code.