Full Report
When the mmap() system call is made, the kernel generates a structure to represent this allocated memory in the Virtual Memory Area (VMA). The structure vm_area_struct contains various items for flags and properties for the memory section. VMAs were previously managed by red-black trees. Now, they use Maple Trees (a B-tree data type for storing non-overlapping ranges). The reason for this change is that the Maple Trees are RCU safe. Read Copy Update (RCU) is a pattern to make reads memory safe even if they are being copied or updated. This allows for read to occur concurrently to writes. Within a maple tree, a maple node either represents a VMA or a gap; there shouldn't be a gap between two intervals. When during concurrent modification, there are restrictions put in place; an exclusive lock is required by all writers. For reading, the MM read-write lock can be taken, but results in slower times. Instead, a read can be performed on the section without taking the lock, which is done in performance critical situations. On a stack expansion, the memory automatically grows. This requires editing the VMA maple tree to add this change. In some situations, the operation can be performed atomically, meaning that it's not a problem. But, when the neighboring node has the MAP_GROWSDOWN flag, this operation CANNOT be performed atomically. When the gap needs to be removed (aka removal of the node), a new node must be created instead of simply altering the old one. This results in the old node being destroyed in a RCU callback. The RCU callback is invoked only after all pre-existing RCU critical sections have concluded. When accessing VMAs with the MM read lock held, it does not enter the critical RCU section. Why is this bad? The callback can be invoked at any time, resulting in a use after free when attempting to access it once again. According to the author, this was exploited in the locked down KCTF environment. This means it's exploitable on nearly all systems. Additionally, this claims to be the first use after free by RCU bug that's happened. Super interesting post and an extremely deep bug.
Analysis Summary
# Vulnerability: StackRot - Use-After-Free in Linux Kernel VMA Maple Tree Management
## CVE Details
- CVE ID: CVE-2023-3269 (Implied by context, explicitly mentioned as "StackRot (CVE-2023-3269)")
- CVSS Score: Not explicitly provided, but implied High severity due to local privilege escalation.
- CWE: CWE-416: Use After Free
## Affected Systems
- Products: Linux Kernel
- Versions: 6.1 through 6.4 (The flaw exists since version 6.1 when VMA management switched to Maple Trees).
- Configurations: Affects nearly all kernel configurations, exploitable even without `CONFIG_PREEMPT` or `CONFIG_SLAB_MERGE_DEFAULT`. The vulnerability is triggered during stack expansion when a neighboring VMA has the `MAP_GROWSDOWN` flag.
## Vulnerability Description
The vulnerability, dubbed "StackRot," resides in the Linux kernel's Virtual Memory Area (VMA) management subsystem, specifically its use of Maple Trees (a B-tree structure replacing older red-black trees for RCU safety).
The flaw occurs during specific stack expansion operations (`mmap()` related growth) involving a VMA that has the neighboring VMA marked with the `MAP_GROWSDOWN` flag. When this occurs, the memory gap between the two regions must be removed, which forces a node replacement in the Maple Tree rather than an atomic update.
Because Maple Trees are RCU-safe, node destruction is deferred via an RCU callback, ensuring memory is only freed after all pre-existing RCU critical sections complete. However, standard VMA access while holding the `mm` read lock *does not* enter an RCU critical section. This allows the RCU callback to execute, freeing the old node, while the kernel code re-acquires the read lock (or otherwise accesses the memory structure) expecting it to still exist, resulting in a Use-After-Free (UAF).
## Exploitation
- Status: Successfully demonstrated in the locked-down Google kCTF VRP environment. Complete exploit code and write-up promised publicly by end of July 2023.
- Complexity: Medium to High (Described as challenging due to the necessary timing required to exploit the UAF relative to the RCU grace period, though successfully demonstrated).
- Attack Vector: Local
## Impact
- Confidentiality: High (Potential kernel memory reading/leaking).
- Integrity: High (Potential kernel code execution leading to privilege escalation).
- Availability: Medium (General system instability/crash via UAF if exploitation fails).
## Remediation
### Patches
The fix involves modifying how node replacement and VMA access are handled to ensure proper locking or synchronization around the RCU destructive callbacks. Patches were merged into Linus' tree on June 28th, 2023.
- **Merged into Linus' Tree (mainline):** Commit hash referencing the fix series.
- **Backported to Stable Kernels (effective July 1st):**
- Linux 6.4.1
- Linux 6.3.11
- Linux 6.1.37
### Workarounds
The description does not explicitly list workarounds, but mitigating the conditions that trigger the structure replacement (e.g., avoiding specific memory layout configurations that force non-atomic node removal during stack growth) may temporarily limit exposure until patching. However, given the severity and configuration independence, patching is the primary mitigation.
## Detection
- Indicators of Compromise: Unusual kernel memory corruption or allocation/deallocation patterns immediately following memory mapping operations, particularly stack expansion.
- Detection methods and tools: Standard kernel debugging tools (like KASAN or tracing RCU callbacks) may assist in identifying the underlying UAF condition if exploitation is attempted.
## References
- Vendor Advisories: Linux Kernel Security Team / Linus Torvalds' Tree merge messages.
- Relevant links - defanged:
- github dot com/lrh2000/StackRot
- git kernel org/pub/scm/linux/kernel/git/torvalds/linux git/commit/?id=9471f1f2f50282b9e8f59198ec6bb738b4ccc009