Page-Oriented Programming: Subverting Control-Flow Integrity of Commodity Operating System Kernels with Non-Writable Code Pages
Seunghun Han, Seong-Joong Kim, Jae-Cheol Ryou
33rd USENIX Security Symposium · Day 1 · USENIX Security '24 · USENIX Security '24
Overview
In the ever-escalating arms race between attackers and defenders, the integrity of operating system kernels remains a paramount concern. This talk, "Page-Oriented Programming: Subverting Control-Flow Integrity of Commodity Operating System Kernels with Non-Writable Code Pages," presented by Seunghun Han and his colleagues Seong-Joong Kim and Jae-Cheol Ryou at USENIX Security '24, unveils a novel and sophisticated attack technique dubbed Page-Oriented Programming (PoP). PoP revisits traditional page mapping attacks, demonstrating a potent new method to bypass even the most advanced, state-of-the-art Control-Flow Integrity (CFI) implementations, including those fortified by hardware-assisted mechanisms like Intel Control-flow Enforcement Technology (CET).

Key moments
- 0:00 Introduction to Page-Oriented Programming and CFI bypass
- 2:00 How commodity OSes protect non-writable code with page tables
- 4:50 Identifying the blind spot: identical page offsets and physical remapping
- 5:20 Introduction to Page-Oriented Programming (POP) attack methodology
- 6:00 Deep dive into POP's Page Carving and Stitching stages
- 8:00 Evaluation setup and proof of concept using CVE-2013-2595
- 9:00 Demonstrating POP attack to hijack commitcreds function
Page-Oriented Programming: Subverting Control-Flow Integrity of Commodity Operating System Kernels with Non-Writable Code Pages
Speakers: Seunghun Han; Seong-Joong Kim; Jae-Cheol Ryou
Conference: USENIX Security '24
YouTube: https://www.youtube.com/watch?v=wSMByLg-ibs
Overview
In the ever-escalating arms race between attackers and defenders, the integrity of operating system kernels remains a paramount concern. This talk, "Page-Oriented Programming: Subverting Control-Flow Integrity of Commodity Operating System Kernels with Non-Writable Code Pages," presented by Seunghun Han and his colleagues Seong-Joong Kim and Jae-Cheol Ryou at USENIX Security '24, unveils a novel and sophisticated attack technique dubbed Page-Oriented Programming (PoP). PoP revisits traditional page mapping attacks, demonstrating a potent new method to bypass even the most advanced, state-of-the-art Control-Flow Integrity (CFI) implementations, including those fortified by hardware-assisted mechanisms like Intel Control-flow Enforcement Technology (CET).
The core of this research lies in identifying critical blind spots within current security paradigms that assume the inviolability of non-writable code pages. While existing defenses meticulously ensure that code regions cannot be directly modified by attackers, PoP cleverly manipulates page tables to remap physical pages, effectively creating arbitrary control flows without altering the code itself. This allows an attacker, assumed to possess an arbitrary kernel memory read and write vulnerability, to subvert CFI enforcement and achieve privilege escalation by orchestrating the execution of sensitive kernel functions through seemingly innocuous system calls. The findings presented in this talk are crucial for understanding the evolving threat landscape and for developing more robust kernel security architectures.
Background
▶ Watch: Introduction to Page-Oriented Programming and CFI bypass (0:00)
Memory corruption vulnerabilities have long been a favored avenue for attackers seeking to hijack program control flow. To counter this, Control-Flow Integrity (CFI) was proposed as a fundamental defense mechanism. CFI operates by creating a Control-Flow Graph (CFG), a static representation of all legitimate execution paths within a program. During runtime, CFI monitors indirect branches (like function pointers or returns) and verifies that their targets conform to the pre-defined CFG. If an attempt is made to jump to an unauthorized or "disfunction" target, the malicious flow is detected and blocked.
While academic research has made significant strides in reducing the size of potential branch target sets, practical CFI implementations prioritize deployability and integration with existing compilation toolchains. These often leverage Virtual Machine (VM)-based or function-type-based verification methods, relying on static CFGs generated from source code. A critical evolution in this space is Hardware-Assisted CFI, which combines software-based CFI with hardware features. Intel's Control-flow Enforcement Technology (CET) is a prime example, offering Indirect Branch Tracking (IBT) to restrict indirect branch targets to valid code positions and a Shadow Stack to protect return addresses. The talk specifically targets modern, strict CFI policies like Clang CFI and Fine IBT, which are deployed in commodity operating systems.
A cornerstone of CFI's effectiveness is the assurance of non-writable code. If an attacker could modify the CFI enforcement code itself, the entire protection mechanism would be neutralized. Commodity operating systems employ sophisticated CPU address translation mechanisms to enforce this. At the kernel level, page tables define memory permissions (e.g., read, write, execute). In virtualized environments, hypervisors add a second layer of translation using Second-Level Address Translation (SLAT) tables, such as Shadow RAM (SRAT) tables. These SRAT tables map Guest Physical Addresses (GPA) to Host Physical Addresses (HPA), acting as an additional barrier. Even if an attacker gains the ability to modify kernel page tables and grant write permissions to code pages, SRAT tables are designed to retain the original non-writable permissions, theoretically preventing unauthorized code alterations.
However, the authors identify a crucial distinction: these mechanisms primarily ensure the non-writability of pages but do not inherently guarantee the integrity of the code area against logical remapping. The attacker model for PoP assumes a system fortified with these hardware-assisted CFI policies and hypervisor-based page-level write protection, but also presumes the attacker possesses an arbitrary kernel memory read and write vulnerability. This capability, while potent, is not considered overestimated given prior research into kernel vulnerabilities. The central question posed by the researchers is whether page-level protection, specifically SRAT tables protecting GPA to HPA translations, is truly sufficient when an attacker can manipulate page tables to remap Guest Logical Addresses (GLA) to different Guest Physical Addresses (GPA), thereby altering the logical view of code without directly modifying its content.
Key Findings
▶ Watch: Identifying the blind spot: identical page offsets and physical remapping (4:50)
The research meticulously uncovers two critical "blind spots" in existing kernel security mechanisms that PoP exploits. The first blind spot questions the sufficiency of page-level protection for ensuring non-writable code. While SRAT tables effectively protect Guest Physical Addresses (GPA) to Host Physical Addresses (HPA) translations, they do not inherently prevent an attacker from manipulating the kernel's own page tables to remap Guest Logical Addresses (GLA) to different GPAs. This means that an attacker, with arbitrary kernel memory read and write capabilities, can logically change which physical page a specific logical address points to, even if the physical content of the original and new pages remains non-writable.
The second blind spot concerns the efficacy of Indirect Branch Tracking (IBT) in detecting control flow deviations. IBT restricts indirect branch targets to valid code positions, and direct branch targets are fixed within the code. However, this "fixed" nature applies only to the logical address space. If an attacker can remap the underlying physical pages, the logical address might still point to a valid code location, but that code location might now correspond to a completely different, security-sensitive physical function.
These observations lead to the core insight of Page-Oriented Programming: if the page offsets of a normal kernel function (e.g., a benign system call) and a sensitive kernel function (e.g., one that grants root privileges) are identical, and an attacker can modify the physical addresses pointed to by the page table entries for the normal function to those of the sensitive function, then the attacker can execute the sensitive function using the normal system call with arbitrary arguments. The CFI enforcement mechanisms, unaware of this underlying page remapping, would perceive the execution as legitimate because the logical address being jumped to still corresponds to a valid code page, albeit one that has been secretly swapped.
Page-Oriented Programming (PoP) is introduced as a novel attack technique that leverages these weaknesses. PoP "programs" kernel page tables using an arbitrary kernel memory read and write vulnerability, allowing the attacker to construct entirely new, arbitrary control flows that bypass existing CFI enforcement. This attack effectively re-visits and weaponizes page mapping vulnerabilities, demonstrating that even with non-writable code pages and hardware-assisted CFI, the integrity of control flow can be subverted through clever manipulation of the memory translation layers.
Technical Deep Dive
▶ Watch: Introduction to Page-Oriented Programming (POP) attack methodology (5:20)
Page-Oriented Programming (PoP) is a sophisticated, multi-stage attack designed to create arbitrary control flows by manipulating kernel page tables. It operates in three distinct phases: Page Carving, Page Stitching, and Page Flushing.
The first stage, Page Carving, focuses on identifying the necessary building blocks for the attack: system call candidates and kernel gadgets. System call candidates are identified as system call stubs (e.g., x64 and i32s prefixes) that can serve as entry points for the attacker's crafted control flow. Two rules are applied to select suitable candidates: first, system calls containing tail calls are excluded to simplify control flow; second, the first direct branch within the candidate must be reachable with attacker-controlled arguments. The analysis revealed over 220 such candidates. A notable characteristic observed was that the branch targets of these system call candidates were consistently aligned by 16 bytes.
Next, kernel gadgets are identified. These are small, existing code sequences within the kernel that can be chained together. The researchers categorize them into:
- Core gadgets: These are essential for linking system call candidates to the desired security-sensitive functions. They perform specific operations crucial for the attack's objective.
- No-operation (NOP) gadgets: These are used to "unlink" or effectively bypass unessential functions from the original control flow path of a security-sensitive function. This is critical for simplifying the target function's execution path and preventing "remapping explosion."
The second stage, Page Stitching, is the core of PoP and involves two crucial jobs. The first is training gadgets and data to create the new control flow. This is achieved by remapping the physical pages of the identified gadgets to arbitrary logical addresses using page table manipulations. The researchers describe several page stitching methods:
- Direct Page Training: Remaps a physical page directly to a desired logical address.
- Indirect Core Training: Involves remapping pages such that an indirect branch from a gadget leads to another desired gadget or function.
- Direct-to-Indirect Core Training: A combination, where a direct branch leads to an address that, after remapping, becomes an indirect branch leading to a further target.
These remapping operations effectively create a new virtual memory layout for the kernel, where specific logical addresses now point to different physical code pages than originally intended.
The second job of Page Stitching is avoiding remapping explosion. When a function is remapped, all its sub-functions and related data dependencies would ideally also need to be remapped to maintain functionality. This can quickly lead to an unmanageable number of remapping operations. To mitigate this, unessential sub-functions within the target security-sensitive function are replaced with NOP gadgets. By remapping these unessential sub-functions' logical addresses to NOP gadget physical pages, the attacker can effectively "skip" them, streamlining the execution path to the desired sensitive operation.
A detailed analysis of gadget distributions was conducted. Over 10,000 core and NOP function gadgets were identified, a number deemed sufficient for constructing complex attack chains. For pure gadgets (code units of average 32 bytes across all page offsets), most were found to be unaligned. This initially presented a challenge, as system call candidates (whose branch targets were 16-byte aligned) could not directly utilize these unaligned pure gadgets. However, a critical discovery was made: the targets of aligned pure core gadgets were themselves often unaligned. This allowed the aligned pure core gadgets to serve as "bridges," enabling the attacker to transition from aligned system call candidates to the more numerous unaligned pure gadgets, thereby expanding the attacker's usable gadget pool significantly.
The final stage is Page Flushing. After manipulating the page tables, the system's Translation Lookaside Buffer (TLB) holds stale mappings. To ensure the CPU loads the newly crafted page table entries, these stale mappings must be flushed. The researchers employed a straightforward approach: they removed the Global bit from the relevant Page Table Entries (PTEs) that were targeted for remapping. Removing the Global bit lowers the priority of these entries in the TLB, making them more susceptible to being flushed by other page table entries over time. While not an immediate flush, this method eventually ensures that the CPU consults the updated page tables and loads the new, attacker-controlled mappings.
Demo / Proof of Concept
▶ Watch: Evaluation setup and proof of concept using CVE-2013-2595 (8:00)
To validate the feasibility and impact of Page-Oriented Programming, the researchers developed a comprehensive proof-of-concept exploit. The evaluation system was configured to represent a commodity operating system with robust defenses: it featured a CT-enabled CPU, ran Ubuntu version 22.04 with KVM version 6, and utilized the open-source hypervisor Shadowbox. This setup allowed the team to target and evaluate PoP against state-of-the-art CFI implementations, specifically Clang Kernel CFI and Fine IBT, across various kernel versions and configurations.
The chosen vulnerability for the exploit was CVE-2013-2595. This particular CVE was selected because it provides the essential page mapping capability required for PoP to function, making it an ideal candidate for demonstrating the attack. Leveraging this vulnerability, the exploit code was able to load and identify critical symbols from the kernel binary and memory, break Kernel Address Randomization (KASLR) (referred to as Kernel ACR in the talk), identify crucial kernel data structures, and subsequently perform the PoP stages.
The demonstration focused on achieving privilege escalation. The target was a security-sensitive kernel function, commit_creds, which is responsible for updating the credentials of the current process, effectively allowing a user to gain root privileges. Prior to executing PoP, the commit_creds function was observed to be legitimately connected to a function named sid within the kernel's control flow. Furthermore, commit_creds had two data dependencies and invoked seven sub-functions, representing a complex legitimate execution path.
After the successful execution of the PoP exploit, a dramatic alteration in the kernel's control flow was observed. The commit_creds function was no longer connected to sid. Instead, the PoP attack had directly linked commit_creds to the _sys_removexattr function. This was achieved by remapping the physical pages of commit_creds and its required data to new logical addresses. Specifically, the physical pages of these functions and data were remapped to their original positions plus an offset of 0x38a3f000. To manage complexity and prevent remapping explosion, three unessential sub-functions originally called by commit_creds were identified and replaced with NOP gadgets. This meant that when _sys_removexattr was invoked (which the attacker could trigger as a normal system call), the remapped commit_creds function would execute, but its unessential sub-functions would be skipped, leading directly to the privilege escalation logic.
The outcome was a successful privilege escalation to root using the _sys_removexattr function. This concrete demonstration unequivocally proved that PoP can bypass advanced CFI mechanisms and hardware-assisted protections, achieving a critical security compromise by manipulating the underlying memory translation layer without directly modifying protected kernel code.
Defensive Implications
▶ Watch: Demonstrating POP attack to hijack commit_creds function (9:00)
The revelations from the Page-Oriented Programming research highlight a significant vulnerability in the current paradigm of kernel security, even with state-of-the-art CFI and hardware-assisted protections. The attack demonstrates that existing mitigations such as page table protection, kernel compartmentalization, and data flow integrity are insufficient to prevent page mapping attacks. While these defenses are effective against direct code modification or unauthorized data access, they do not inherently guard against the logical remapping of code pages that PoP exploits.
The speakers propose that a more fundamental solution is required, pointing to the Redirection Protection feature from Intel as a potential answer. This feature, designed to enhance virtualization security, fundamentally alters how guest memory addresses are translated. Instead of relying on the guest operating system's page tables to translate Guest Logical Addresses (GLA) to Guest Physical Addresses (GPA), Redirection Protection introduces Hypervisor-managed Linear Address Translation (HMLAT). With HMLAT, the hypervisor directly translates GLAs to GPAs, effectively bypassing and invalidating the guest kernel's ability to manipulate its own page tables for remapping purposes.
By placing the GLA-to-GPA translation under the hypervisor's control, HMLAT can prevent an attacker within the guest kernel from performing the page table manipulations central to PoP. If the hypervisor enforces a consistent and immutable mapping between logical and physical pages for critical kernel code, any attempt by the guest kernel to remap these pages would be blocked at the hypervisor level. This would negate the core mechanism of PoP, as the attacker would no longer be able to redirect logical addresses to arbitrary physical pages of their choosing.
However, the speaker also candidly acknowledged that even this advanced feature would likely face intense scrutiny from the research community. As history has shown, new security features often become new targets for analysis and potential bypasses. The introduction of Redirection Protection would shift the attack surface, potentially leading to new research focusing on vulnerabilities within the HMLAT implementation itself or its interaction with other system components. Nevertheless, Intel's Redirection Protection, by fundamentally altering the memory translation architecture, offers a promising direction for developing more robust defenses against sophisticated page mapping attacks like PoP.
Key Takeaways
- PoP bypasses advanced CFI: Page-Oriented Programming (PoP) effectively subverts state-of-the-art Control-Flow Integrity (CFI) implementations, including those fortified by hardware-assisted mechanisms like Intel CET, by exploiting blind spots in page-level non-writable code protection and indirect branch tracking.
- Three-stage attack methodology: The attack comprises three distinct stages: Page Carving (identifying syscall candidates and gadgets), Page Stitching (remapping physical pages via page tables to create new control flows and mitigating remapping explosion), and Page Flushing (invalidating stale TLB entries).
- Leverages kernel memory vulnerabilities: PoP relies on the attacker possessing an arbitrary kernel memory read and write vulnerability (demonstrated with CVE-2013-2595) to manipulate page table entries and orchestrate privilege escalation.
- Gadget feasibility confirmed: Extensive analysis revealed sufficient numbers of both function and pure gadgets. Crucially, the discovery that targets of aligned pure core gadgets were often unaligned allowed them to act as "bridges," enabling the use of a wider range of otherwise inaccessible unaligned gadgets.
- Intel Redirection Protection as a potential defense: Intel's Redirection Protection feature, which utilizes Hypervisor-managed Linear Address Translation (HMLAT) to control GLA-to-GPA mapping, is proposed as a fundamental mitigation against page mapping attacks by preventing guest kernel page table manipulation.
- Highlights architectural blind spots: The research underscores that merely ensuring non-writable code pages is insufficient; true code integrity requires protection against logical remapping of memory, even when the underlying physical pages remain unaltered.
About the Speaker(s)
The talk was presented by Seunghun Han, who noted it was his second presentation at USENIX Security, indicating a sustained contribution to the field of security research. He is the lead author of the paper, collaborating with Seong-Joong Kim and Jae-Cheol Ryou. Together, their work delves into critical aspects of operating system kernel security, particularly the sophisticated techniques attackers can employ to bypass modern defense mechanisms. Their research contributes significantly to understanding the evolving landscape of kernel exploitation and informs the development of more resilient security architectures.
Reviews
Dr. Zero (Offensive Security Researcher) — MUST SEE
This research introduces Page-Oriented Programming (PoP), a novel and technically sophisticated attack that bypasses state-of-the-art kernel CFI, including hardware-assisted mechanisms like Intel CET. By manipulating page tables to remap non-writable code pages, PoP demonstrates a critical architectural blind spot, enabling arbitrary control flow without direct code modification. The work provides a stark reminder that even robust defenses can be undermined by clever exploitation of underlying memory translation layers.
Heather Calloway (CISO) — STRONG ACCEPT
This research uncovers a fundamental blind spot in kernel security, demonstrating how sophisticated page mapping attacks can bypass even hardware-assisted CFI. It demands a re-evaluation of our architectural assumptions regarding kernel integrity and the efficacy of current mitigations. While the immediate operational actions for defenders are limited, the strategic implications for platform security are profound.