In my recent Black Hat USA talk on the attack surface and exploit mitigations in EdgeHTML (Microsoft Edge’s new rendering engine), one of the topics that I discussed was Memory GC (MemGC), a new and improved use-after-free (UAF) exploit mitigation introduced by Microsoft in Edge and IE on Windows 10.

About MemGC

MemGC was first introduced in Edge’s EdgeHTML rendering engine and in IE’s Trident (MSHTML) rendering engine on Windows 10. It is the successor to the Memory Protector UAF exploit mitigation in the aforementioned rendering engines on Windows 10.

Similar to Memory Protector, the purpose of MemGC is to mitigate exploitation of UAF vulnerabilities by preventing the freeing of memory chunks if references to them are found. However, unlike Memory Protector, which only checks the registers and the stack for chunk references, MemGC also scans the contents of MemGC-managed chunks for references. This additional check means that MemGC further decreases the number of usable UAF bugs that an attacker can exploit.

Configuration

MemGC is enabled by default. One way to configure it in both Edge and IE is via the OverrideMemoryProtectionSetting configuration, which can be set via the following registry entry:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main::OverrideMemoryProtectionSetting = %DwordValue%

Where %DwordValue% can be any of the following:

  • 3: MemGC is enabled (default).
  • 2: Memory Protector is enabled (force mark-and-reclaim).
  • 1: Memory Protector is enabled.
  • 0: MemGC and Memory Protector are disabled.

MemGC Heap

MemGC uses a separate managed heap (called the MemGC heap) for object allocation, as well as a concurrent garbage collector that performs a mark-and-sweep operation to automatically identify and reclaim unreferenced chunks in the MemGC heap. MemGC depends on the Chakra JavaScript engine memory management routines for most of its functionality.

The allocation scheme used involves committing chunks of memory called Segments using VirtualAlloc() and then dividing these Segments into 4096-byte Pages. A group of these Pages are then treated as a Block, which is in turn used in the allocation of similarly sized objects.

EdgeHTML/MSHTML DOM objects and many internal rendering engine objects are managed by MemGC. And because MemGC already uses a separate managed heap, the Isolated Heap is unused if MemGC is enabled.

Allocation

In EdgeHTML’s implementation of MemGC, when a MemGC-managed object needs to be allocated, edgehtml!MemoryProtection::HeapAlloc<1>() or edgehtml!MemoryProtection::HeapAllocClear<1>() is called, which in turn calls chakra!MemProtectHeapRootAlloc().

Chakra!MemProtectHeapRootAlloc() will then allocate a chunk from a Block in the appropriate bucket and then flag the chunk as a root. In garbage collection parlance, root means that the object is directly referenced by the program and therefore should not be garbage-collected. Root chunks are also used by the garbage collector when scanning for chunk references.

Protected Freeing

When an object is to be freed, edgehtml!MemoryProtection::HeapFree() is called, which in turn calls chakra!MemProtectHeapUnrootAndZero().

Chakra!MemProtectHeapUnrootAndZero() attempts to locate the Block where the object’s chunk is, zero-out the chunk and then clear the root flag of the chunk. By clearing the root flag, the chunk will become a candidate for garbage collection and will be reclaimed if no references to it are found by the garbage collector (more on this below).

Garbage Collection

Once the total size of the unrooted chunks reaches a dynamically computed threshold value, garbage collection will be triggered via chakra!MemProtectHeap::Collect(). The garbage collection — a complicated process of which only the core functions are described here — will perform a mark-and-sweep operation to reclaim unreferenced unrooted chunks. Some parts of the mark-and-sweep operation are executed on a separate thread (chakra!Memory::Recycler::ThreadProc), which is notified via chakra!Memory::Recycler::StartConcurrent().

In the marking phase, the mark bit for all chunks is first cleared and all root chunks are marked (via chakra!Memory::Recycler::BackgroundResetMarks()). Then the root chunks (via chakra!Memory::Recycler:: ScanImplicitRoots()), registers and stack (via chakra!MemProtectHeap::FindRoots()) are scanned for chunk pointers. Referenced chunks found in the scan are marked. Chunks that are not marked after the marking phase will eventually be made available for reallocation.

Conclusion

Similar to Memory Protector, MemGC will further reduce the number of exploitable use-after-free vulnerabilities in Edge and IE. However, MemGC is also a complex mechanism with a custom heap management and garbage collection scheme. Attackers take advantage of complexity by looking at attack vectors that had been inadvertently introduced or attack techniques that were unwittingly made possible. Needless to say, MemGC deserves scrutiny to identify and eventually improve its potential weaknesses.

As mentioned at the start of this blog post, MemGC is one of the topics recently discussed in my Black Hat USA  2015 presentation. If you are interested in understanding the attack surface and exploit mitigations in EdgeHTML, please check out my slide deck and watch this video with my colleague Chris Poulin. For an even deeper dive into the subject, please download my white paper, Understanding the Attack Surface and Attack Resilience of Project Spartan’s (Edge) New EdgeHTML Rendering Engine.

https://www.youtube.com/watch?v=wJSlNpxum-g

More from Software Vulnerabilities

X-Force releases detection & response framework for managed file transfer software

5 min read - How AI can help defenders scale detection guidance for enterprise software tools If we look back at mass exploitation events that shook the security industry like Log4j, Atlassian, and Microsoft Exchange when these solutions were actively being exploited by attackers, the exploits may have been associated with a different CVE, but the detection and response guidance being released by the various security vendors had many similarities (e.g., Log4shell vs. Log4j2 vs. MOVEit vs. Spring4Shell vs. Microsoft Exchange vs. ProxyShell vs.…

MSMQ QueueJumper (RCE Vulnerability): An in-depth technical analysis

13 min read - The security updates released by Microsoft on April 11, 2023, addressed over 90 individual vulnerabilities. Of particular note was CVE-2023-21554, dubbed QueueJumper, a remote code execution vulnerability affecting the Microsoft Message Queueing (MSMQ) service. MSMQ is an optional Windows component that enables applications to exchange messages via message queues that are reachable both locally and remotely. This analysis was performed in collaboration with the Randori and X-Force Adversary Services teams, by Valentina Palmiotti, Fabius Watson, and Aaron Portnoy. Research motivations…

X-Force prevents zero day from going anywhere

8 min read - This blog was made possible through contributions from Fred Chidsey and Joseph Lozowski. The 2023 X-Force Threat Intelligence Index shows that vulnerability discovery has rapidly increased year-over-year and according to X-Force’s cumulative vulnerability and exploit database, only 3% of vulnerabilities are associated with a zero day. X-Force often observes zero-day exploitation on Internet-facing systems as a vector for initial access however, X-Force has also observed zero-day attacks leveraged by attackers to accomplish their goals and objectives after initial access was…

Topic updates

Get email updates and stay ahead of the latest threats to the security landscape, thought leadership and research.
Subscribe today