The Return Of Stack Overflows In The Linux Kernel

Davide Ornaghi (Offensive Security Specialist · Intré)

HITBSecConf2023 - Amsterdam · Day 2 · CommSec Track

Overview

In this compelling talk at HITB Amsterdam, Davide Ornaghi, an Offensive Security Specialist at Intré, challenges the prevailing notion that stack overflows in the Linux kernel are a relic of the past. Ornaghi presents a detailed analysis of modern kernel exploitation, demonstrating that despite a decade of robust mitigations, these seemingly "common" vulnerabilities can still be leveraged for potent attacks, including remote code execution and privilege escalation. His research highlights a critical blind spot in current kernel defenses: the soft interrupt stack, which remains unrandomized and offers a stable target for attackers.

Watch on YouTube

Visual summary for The Return Of Stack Overflows In The Linux Kernel by Davide Ornaghi
Visual summary for The Return Of Stack Overflows In The Linux Kernel by Davide Ornaghi

Key moments

  1. 0:00 Introduction to Linux kernel stack exploitation
  2. 2:00 Vulnerability trends: Stack overflows are 'killed' but returning
  3. 6:00 Modern kernel mitigations: KASLR, KPTI, SMAP/SMAP
  4. 10:15 NFTable subsystem exploit: Out-of-bounds read and write
  5. 12:15 Speaker's custom stack overflow: Double VLAN tag vulnerability
  6. 16:00 Payload duplication strategy for more code execution space
  7. 18:00 Strategies for safely exiting the interrupt context
  8. 20:50 Proposed mitigation: Soft interrupt kernel stack randomization

The Return Of Stack Overflows In The Linux Kernel

Speakers: Davide Ornaghi, Offensive Security Specialist, Intré

Conference: HITB Amsterdam

YouTube: https://www.youtube.com/watch?v=5b9UlBrzvG0

Overview

In this compelling talk at HITB Amsterdam, Davide Ornaghi, an Offensive Security Specialist at Intré, challenges the prevailing notion that stack overflows in the Linux kernel are a relic of the past. Ornaghi presents a detailed analysis of modern kernel exploitation, demonstrating that despite a decade of robust mitigations, these seemingly "common" vulnerabilities can still be leveraged for potent attacks, including remote code execution and privilege escalation. His research highlights a critical blind spot in current kernel defenses: the soft interrupt stack, which remains unrandomized and offers a stable target for attackers.

Ornaghi's presentation is a deep dive into the evolution of kernel security, tracing the decline of stack overflows and the rise of other vulnerability classes, only to reveal their potential resurgence. He meticulously dissects various kernel mitigations, explaining their mechanisms and, crucially, their limitations. Through the analysis of past and present kernel bugs, including his own discovered vulnerability, Ornaghi illustrates how attackers can bypass sophisticated defenses and achieve full exploit chains. This talk is essential for kernel developers, security researchers, and system administrators seeking to understand the cutting edge of Linux kernel exploitation and the defenses required to counter it.

Background

▶ Watch: Introduction to Linux kernel stack exploitation (0:00)

For many years, stack overflows were considered a foundational vulnerability class, frequently exploited in userland and kernel contexts alike. However, significant advancements in compiler technology and operating system design, coupled with the introduction of robust security mitigations, largely relegated them to historical footnotes in the context of kernel exploitation. Ornaghi's research begins by establishing this historical context, presenting statistics that show a dramatic decrease in reported stack overflows in Linux kernel versions 5.x and 6.x compared to 3.x and 4.x. This decline is attributed to the widespread implementation of mechanisms like stack canaries (stack protectors) and enhanced memory management.

Despite the reduction in stack overflows, other vulnerability classes have risen to prominence. Ornaghi categorizes kernel vulnerabilities, noting that while race conditions, use-after-free, and heap overflows became more common, stack overflows seemed "pretty much killed." He further breaks down vulnerabilities by kernel component, identifying Netfilter, KVM (Kernel-based Virtual Machine), and BPF (Berkeley Packet Filter) as consistently high-impact areas. While BPF has been significantly hardened to limit its use for privilege escalation, KVM remains a target for VM escapes, and Netfilter, due to its complexity and network-facing nature, has been a persistent source of vulnerabilities. It is within the Netfilter subsystem that Ornaghi finds his "safe haven" for exploring new attack vectors.

The talk then introduces the formidable array of kernel mitigations that have been deployed over the past decade, making kernel exploitation a significantly more challenging endeavor. These include:

  • KPTI (Kernel Page-Table Isolation), introduced in 2017, which separates user and kernel page tables to limit the visibility of kernel memory from userland.
  • SMAP (Supervisor Mode Access Prevention) and SMEP (Supervisor Mode Execution Prevention), hardware-assisted protections that prevent the kernel from accessing or executing userland memory, respectively.
  • FGKASLR (Fine-Grained Kernel Address Space Layout Randomization), a more granular form of KASLR that shuffles individual kernel functions at load time, making ROP gadget discovery more difficult.
  • Per-syscall stack offset randomization, an iterative form of stack KASLR that shifts the kernel stack by a random amount upon every syscall exit, complicating stack-based exploits.

These mitigations collectively aim to prevent information leaks, restrict code execution locations, and randomize memory layouts, thereby making traditional stack smashing attacks largely ineffective. Ornaghi's work, however, seeks to demonstrate that these defenses are not impenetrable, especially in specific kernel contexts.

Key Findings

▶ Watch: Modern kernel mitigations: KASLR, KPTI, SMAP/SMAP (6:00)

Ornaghi's primary finding is that stack overflows are far from obsolete in the Linux kernel, especially when targeting specific subsystems and exploiting overlooked contexts. He argues that the perception of their demise is premature, and with careful analysis, they can still be weaponized effectively. His research highlights several critical points:

  1. Resurgence Potential: While statistics show a decline in stack overflows, Ornaghi demonstrates that newly discovered vulnerabilities, particularly in network-related components like Netfilter, can still manifest as powerful stack overflows. He identifies the Netfilter subsystem as a fertile ground for these vulnerabilities, partly due to the trust placed in capabilities like CAP_NET_ADMIN, leading to less stringent code scrutiny.
  1. Mitigation Blind Spots: Modern kernel mitigations, while robust, are not universally applied or equally effective across all execution contexts. Specifically, Ornaghi identifies that per-syscall stack offset randomization—a key defense against stack-based attacks—has no effect within the interrupt context. This creates a stable, unrandomized environment that attackers can leverage for reliable exploitation.
  1. Exploitable Information Leaks: Even seemingly minor vulnerabilities can be chained to achieve significant impact. Ornaghi demonstrates how a small out-of-bounds memcpy in his discovered vulnerability (a double VLAN tag length integer overflow) can be used to leak critical kernel addresses and stack canaries, effectively defeating KASLR and providing the necessary primitives for code execution.
  1. Multi-Stage Exploitation: Due to limitations in the size of controllable kernel memory regions (e.g., NFT registers offering only 64 bytes), successful exploitation often requires a multi-stage approach. This involves using the initial vulnerability to set up a stack pivot or duplicate attacker-controlled data into a larger, accessible kernel memory area, then redirecting execution to a more substantial payload.
  1. Achieving Remote Code Execution (RCE): Ornaghi conclusively shows that these vulnerabilities, particularly when located in network-facing components, can lead to Remote Code Execution. The ability to control the expression pointer within the NFTable execution flow provides a powerful primitive for arbitrary code execution, which can then be escalated to root privileges.

In essence, Ornaghi's key finding is a call to re-evaluate the threat posed by stack overflows in the Linux kernel. He demonstrates that by understanding the nuances of kernel execution contexts and the specific limitations of existing mitigations, attackers can still achieve full exploit chains, leading to severe security compromises.

Technical Deep Dive

▶ Watch: Speaker's custom stack overflow: Double VLAN tag vulnerability (12:15)

The technical core of Ornaghi's talk revolves around understanding and bypassing the formidable array of Linux kernel mitigations. He explains each mitigation and then illustrates how a sophisticated exploit can navigate around them.

Modern Kernel Mitigations and Their Challenges:

  • KPTI (Kernel Page-Table Isolation): Introduced in 2017, KPTI segregates user and kernel page tables. In userland, only a minimal set of kernel pages (e.g., those required for context switching) are visible. This prevents userland code from directly reading or writing to most kernel memory. Bypasses often involve restoring userland page tables via a "trampoline" or using user mode helpers (kernel functions that execute user-specified code in user mode).
  • SMAP/SMEP (Supervisor Mode Access/Execution Prevention): These hardware features (on x86-64, for example) prevent the kernel from accessing (SMAP) or executing (SMEP) memory pages that belong to userland. This directly thwarts attacks that try to inject payloads into userland memory and then jump to them from a compromised kernel context. The common bypass strategy is to keep the entire exploit chain within kernel memory, constructing a ROP (Return-Oriented Programming) chain using only kernel gadgets.
  • FGKASLR (Fine-Grained Kernel Address Space Layout Randomization): A more advanced form of KASLR, FGKASLR shuffles individual kernel functions (or small text sections) at load time. This makes it harder to predict the address of specific functions or ROP gadgets. Ornaghi notes it's not widely implemented in appliances. Bypasses can involve using info leaks to locate a single randomized symbol, then recalculating other symbols based on known offsets from the symbol table. The data section often remains at a fixed offset, allowing user mode helpers to be used.
  • Per-syscall stack offset randomization: This is particularly challenging for stack-based exploits. At every syscall exit, the kernel stack shifts by a random amount. This means any hardcoded stack offsets for overwriting return addresses or injecting payloads will become invalid after the first syscall. Ornaghi highlights that this mitigation has no effect in the interrupt context, which becomes a critical attack vector.

Anatomy of a Successful Stack Overflow in the Modern Kernel:

Ornaghi analyzes several vulnerabilities to illustrate these concepts:

  1. CVE-2004-35 (TIPC Stack Overflow): This older vulnerability, presented at Hack in the Box, involved an 800-byte overrun in the TIPC (Transparent Inter-Process Communication) subsystem. While powerful for its time, it highlights the challenges of modern exploitation. Overwriting the stack canary or crossing guard pages between stack frames would lead to an immediate panic. Furthermore, without disabling KASLR and other mitigations, jumping to arbitrary code or making the stack executable is infeasible. This example serves to contrast past vulnerabilities with the complexities of today.
  1. NFTable OOB Read/Write (Older Exploit Chain): Ornaghi references an exploit in the NFTable subsystem (a successor to IP tables) that involved an out-of-bounds read and write on the stack, specifically targeting the NF table regs structure. This allowed an attacker to read arbitrary memory for info leaks (finding instruction addresses and stack canaries) and to overwrite the RIP (Return Instruction Pointer) in a "stealth way," bypassing the stack canary. A key aspect of this exploit was the ability to choose between the interrupt context (via input chains) and the syscall context (via output chains), allowing the attacker to select the context most favorable for bypassing mitigations.
  1. Davide Ornaghi's Double VLAN Tag Length Integer Overflow (CVE-2023-XXXX, likely unpublished at talk time): This is Ornaghi's own discovery, a pretty simple stack overflow in the Netfilter component. The vulnerability arises from an incorrect calculation of the double VLAN tag length within an SKB packet being forwarded. An integer overflow occurs, leading to an out-of-bounds memcpy of up to 251 bytes into the destination NFT registers.
  • Info Leak: By triggering the overflow from reg[0] and overwriting subsequent registers, an attacker can read sensitive kernel information (text addresses, stack canaries) from the NFT registers, effectively defeating KASLR.
  • Memory Corruption for Code Execution: To achieve code execution, the overflow is triggered from reg[15], overwriting structures immediately following it. A detailed analysis revealed a specific path to overwrite an expression pointer within a structure that controls the execution flow of NFT rules. By controlling this pointer, an attacker gains a "free jump instruction" to an arbitrary address.

The challenge with this approach is the limited size of the NFT registers (only 64 bytes), which is insufficient for a full ROP chain or complex payload. This necessitates a multi-stage approach, which he details in the demo section.

Demo / Proof of Concept

▶ Watch: Payload duplication strategy for more code execution space (16:00)

Ornaghi's proof of concept demonstrates a full exploit chain for his double VLAN tag length integer overflow, illustrating how to overcome the limitations of small write primitives and various kernel mitigations to achieve privilege escalation to root.

The exploit unfolds in multiple stages:

  1. Initial Setup and Payload Duplication:
  • The attacker first sets up the NFTable rules with a stack pivot instruction as part of their initial payload.
  • They then trigger the vulnerability. The memcpy operation, due to the integer overflow, not only writes to the target NFT registers but also duplicates the attacker's initial content (including the stack pivot) into an adjacent, controlled area of the jump stack. This effectively creates a larger, attacker-controlled memory region in the kernel.
  1. Stage Two Payload Injection:
  • With the initial payload duplicated, the attacker then refills the NFT registers with a second, larger payload. This "stage two" payload contains the actual ROP chain designed to elevate privileges.
  1. Redirecting Execution:
  • As described in the technical deep dive, the vulnerability allows the attacker to overwrite the expression pointer within the NFT rules execution flow.
  • This pointer is redirected to point to the duplicated "stage one" payload (the stack pivot).
  • The stage one payload then executes, performing a stack pivot to the "stage two" payload (the ROP chain) that was injected into the NFT registers.
  1. Privilege Escalation:
  • The ROP chain (stage two) then executes. A common technique for privilege escalation in the Linux kernel is to use user mode helpers. Ornaghi specifically targets the modprobe_path variable. By overwriting modprobe_path with a path to an attacker-controlled script, the next attempt by the kernel to load a non-existent module will execute the attacker's script as root.
  1. Graceful Exit from Interrupt Context:
  • A critical and often overlooked aspect of kernel exploitation is exiting the compromised context gracefully to prevent a kernel panic. Since the exploit chain operates within the interrupt context (where per-syscall stack offset randomization does not apply), the attacker must ensure a clean return.
  • Ornaghi explains the use of the swapgs_restore_regs_and_return_to_usermode symbol, which performs the necessary context switch (swapping the GS register) and then executes the IRETQ instruction to return to userland, restoring the stack pointer, instruction pointer, and segment registers.
  • He also identifies that the do_softirq function restores the syscall stack. By carefully choosing a function within the current stack frame to return to (e.g., NF_hooks_low), the attacker can prevent deadlocks and ensure a stable exit, effectively "killing the function before the problem is detected."

This multi-stage exploit, leveraging the unrandomized interrupt context, the limited write primitive, and a graceful exit, demonstrates a full, practical exploit chain for a modern kernel stack overflow, resulting in root privileges.

Defensive Implications

▶ Watch: Proposed mitigation: Soft interrupt kernel stack randomization (20:50)

Ornaghi's research not only highlights the vulnerabilities but also proposes concrete defensive measures to mitigate the risks posed by the return of stack overflows in the Linux kernel. He emphasizes that while existing mitigations are strong, specific contexts (like the soft interrupt stack) remain exposed.

  1. Harden User Mode Helpers:
  • One immediate recommendation is to prevent the common privilege escalation technique of overwriting modprobe_path. This can be achieved by configuring user mode helpers as a static variable at compile time. If CONFIG_STATIC_USERMODEHELPER is enabled, the modprobe_path symbol becomes immutable at runtime, and attempts to overwrite it will be ignored, forcing the kernel to use the pre-defined path. This significantly limits the utility of user mode helper-based privilege escalation.
  1. In-Kernel Pointer Authentication (ARMv8.3 PAuth):
  • Ornaghi points to existing hardware-level solutions as a strong defense. ARMv8.3 Pointer Authentication (PAuth), merged into the Linux kernel since version 5.7, allocates a few bits in each pointer to store a cryptographic signature. Before a pointer is used, its signature is validated. This makes ROP chains significantly harder to construct and execute, as attackers cannot jump to arbitrary locations or gadgets without a valid signature. While currently specific to ARM architectures, similar concepts could be explored for other platforms.
  1. Soft Interrupt Kernel Stack Randomization (Proposed Mitigation):
  • This is Ornaghi's most significant defensive proposal, directly addressing the core vulnerability he identified. He explains the different stack contexts:
  • Userland Stack: The normal stack for user processes.
  • Kernel Stack (per-thread): Activated during a syscall; subject to per-syscall stack offset randomization.
  • Hard Interrupt Stack (per-CPU): Used for immediate hardware interrupts (e.g., NIC card packet reception); also per-CPU.
  • Soft Interrupt Stack (per-CPU): Used for deferred interrupt processing (e.g., do_softirq function called by a kernel thread). Crucially, this stack currently lacks randomization.
  • Because the soft interrupt stack address is always the same for a given CPU, any info leak (even from the syscall context) that reveals its base address remains valid until reboot. This provides a stable target for attackers.
  • Ornaghi proposes adding an arbitrary offset to the soft interrupt stack, similar to how the main kernel stack is randomized. However, he cautions against reusing the exact same offset as the kernel stack, as a leak in the syscall context would then compromise the soft interrupt stack randomization as well. A distinct, independent randomization mechanism is needed.

By implementing these measures, particularly the soft interrupt stack randomization, the Linux kernel can significantly raise the bar for exploiting stack overflows in critical network subsystems, closing a crucial gap in its defense posture.

Key Takeaways

  • Stack overflows are not dead in the Linux kernel: Despite advanced mitigations, specific contexts like the soft interrupt stack remain vulnerable, making stack overflows a viable attack vector for skilled adversaries.
  • Mitigation blind spots exist: Modern defenses like per-syscall stack offset randomization are ineffective in the interrupt context, providing a stable, unrandomized environment for exploit development.
  • Netfilter is a critical attack surface: Due to its complexity, network-facing nature, and reliance on capabilities like CAP_NET_ADMIN, the Netfilter subsystem continues to be a fertile ground for discovering and exploiting kernel vulnerabilities, including stack overflows.
  • Multi-stage exploits are essential for small primitives: Limited write sizes (e.g., 64 bytes in NFT registers) necessitate sophisticated multi-stage payloads involving stack pivots and payload duplication to achieve full exploit chains.
  • Graceful exit is crucial for stability: Successful kernel exploits must include mechanisms to exit the compromised kernel context cleanly (e.g., using swapgs_restore_regs_and_return_to_usermode) to prevent kernel panics and ensure persistence.
  • Soft interrupt stack randomization is a vital next step: Implementing an independent randomization mechanism for the soft interrupt stack is crucial to close a significant security gap and prevent reliable exploitation of vulnerabilities in this context.

About the Speaker(s)

Davide Ornaghi is an Offensive Security Specialist at Intré, a newly founded company. He is also an instructor for malware analysis and pen testing at various Italian universities and holds an MSC in IT security. Ornaghi describes himself as a "zero-day enjoyer," passionate about expanding his knowledge by reading write-ups and articles on diverse Linux vulnerabilities. His research focuses on identifying and exploiting vulnerabilities within the Linux kernel, particularly in areas like the Netfilter subsystem and stack exploitation, with a keen interest in understanding and bypassing modern kernel mitigations.

Reviews

Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT

Solid kernel exploitation research that identifies a real gap in Linux defenses — the unrandomized soft interrupt stack — and demonstrates a full exploit chain against his own Netfilter bug. Not revolutionary, but technically competent work that should force a conversation about hardening interrupt contexts.

Heather Calloway (CISO) — STRONG ACCEPT

Solid original research identifying a real gap in Linux kernel defenses — the unrandomized soft interrupt stack. Any organization running Linux at the edge or in network-facing roles should understand this affects their patching calculus and hardening posture.

→ Top-rated talks at HITBSecConf2023 - Amsterdam

All talks from HITBSecConf2023 - Amsterdam