Breaking the Sound Barrier: Exploiting CoreAudio via Mach Message Fuzzing
Dillon Franke (Senior Security Engineer · Google)
CODE BLUE 2025 · Day 1 · Track 1 (Hall B)
Overview
In this compelling talk at CODE BLUE, Dillon Franke, a Senior Security Engineer at Google and a researcher with Google Project Zero, unveiled groundbreaking research into exploiting CoreAudio on macOS and iOS. The presentation, titled "Breaking the Sound Barrier: Exploiting CoreAudio via Mach Message Fuzzing," detailed a sophisticated methodology for discovering and exploiting vulnerabilities within Apple's interprocess communication (IPC) mechanisms, specifically Mach messages. Franke's work highlights the critical role of IPC in modern operating systems as a bridge between sandboxed and privileged processes, making it a prime target for sandbox escapes and privilege escalation.

Key moments
- 0:00 Introduction and talk agenda
- 2:00 What is fuzzing? Knowledge-driven approach
- 6:00 Understanding Mach ports and services
- 15:00 Designing the direct fuzzing harness
- 25:00 Harness iteration: API call chaining
- 30:00 Type confusion vulnerability discovery
- 37:00 Heap spraying with property lists for exploitation
- 41:00 Live demo of the sandbox escape exploit
Breaking the Sound Barrier: Exploiting CoreAudio via Mach Message Fuzzing
Speakers: Dillon Franke, Senior Security Engineer, Google
Conference: CODE BLUE
YouTube: https://www.youtube.com/watch?v=UM2BlifbRKw
Overview
In this compelling talk at CODE BLUE, Dillon Franke, a Senior Security Engineer at Google and a researcher with Google Project Zero, unveiled groundbreaking research into exploiting CoreAudio on macOS and iOS. The presentation, titled "Breaking the Sound Barrier: Exploiting CoreAudio via Mach Message Fuzzing," detailed a sophisticated methodology for discovering and exploiting vulnerabilities within Apple's interprocess communication (IPC) mechanisms, specifically Mach messages. Franke's work highlights the critical role of IPC in modern operating systems as a bridge between sandboxed and privileged processes, making it a prime target for sandbox escapes and privilege escalation.
The core of Franke's research revolved around a novel approach to knowledge-driven fuzzing, combining automated input generation with deep manual analysis to navigate the complexities of closed-source Apple binaries. This talk not only exposed a critical type confusion vulnerability within the highly privileged coreaudiod service but also provided a meticulous walkthrough of the entire attack cycle, from target identification and fuzzer development to the intricate details of exploit chaining. The findings underscore the continuous need for robust security in core system services and offer invaluable insights for both offensive and defensive security practitioners operating within the Apple ecosystem.
Background
▶ Watch: Introduction and talk agenda (0:00)
The modern security landscape, particularly concerning web browsers, often necessitates a sandbox escape in addition to a remote code execution (RCE) vulnerability. Interprocess Communication (IPC) mechanisms, such as Mach messages on Apple systems, frequently serve as these crucial bridges between highly restricted sandboxed processes and more privileged, unrestricted system services. This makes IPC a natural and historically abused attack vector for escalating privileges or breaking out of sandboxes. Franke referenced prior work by notable researchers like Ian Beer of Project Zero, who demonstrated Mach message abuse for heap spraying and sandbox escapes, and a methodical browser exploitation approach by RET 2 systems that leveraged Mach message fuzzing.
Mach IPC operates on the concept of Mach ports, which are kernel-managed message queues. Processes interact with these ports using send rights (to send messages) or receive rights (to receive messages). Establishing communication often involves the bootstrap server, a special Mach port that helps processes discover and connect to named Mach services. Any process can send to the bootstrap server, and a service registers itself with a unique identifier (e.g., com.apple.codeblue), allowing other processes to request a send right to its receive port.
To identify promising targets, Franke focused on system daemons – privileged services launched by launchd and defined in Plist files. The goal was to find a Mach service accessible from a sandbox. This was achieved by examining SB files (sandbox profiles in Scheme format) or dynamically using the SB tool (by Jonathan Leven), which enumerates Mach services a given process (like Safari's WebKit GPU process) is permitted to interact with. These accessible services represent potential sandbox escape vectors. The chosen target, CoreAudio, specifically the coreaudiodd daemon, stood out due to its exposure via the com.apple.audio.coreaudiod service, its interaction with impactful applications (including Safari GPU), a large number of message handlers, and its likely elevated privileges due to controlling audio hardware. The fact that coreaudiod and its underlying Core Audio framework are closed-source presented a significant reverse engineering challenge, making knowledge-driven fuzzing an ideal approach.
Franke’s methodology for vulnerability research is rooted in knowledge-driven fuzzing, an approach that balances the speed of automation with the depth of manual analysis. Unlike purely "black box" fuzzing, this method involves:
- Automation: Using fuzzers to rapidly generate unexpected inputs and identify interesting system reactions (e.g., crashes). This is about "moving fast and breaking things."
- Manual Analysis: Deeply understanding the codebase through crash analysis, code coverage feedback, and debugging. Researchers ask: "Why is coverage plateauing?", "Why are these errors occurring?", and use this understanding to guide and improve the fuzzer. This iterative process allows for a comprehensive understanding of the target system, even with closed-source code.
Key Findings
▶ Watch: Understanding Mach ports and services (6:00)
Dillon Franke's research culminated in several significant findings, demonstrating the efficacy of his knowledge-driven fuzzing methodology against Apple's closed-source CoreAudio framework:
- Discovery of a Critical Type Confusion Vulnerability: The primary finding was a severe type confusion vulnerability within the Hardware Abstraction Layer (HAL) of CoreAudio. This vulnerability, triggered in the
XIOContext::fetchWorkgroupPortfunction, allowed an attacker to manipulate an object's type, causing the system to dereference an unexpected memory location. This ultimately led to a virtual function call on attacker-controlled data, providing a powerful primitive for arbitrary code execution. The vulnerability was reported to Apple on October 9, 2024, and subsequently fixed on December 11, 2024.
- Identification of an Uninitialized Memory Bug: During the exploitation phase, Franke uncovered an uninitialized memory bug within newly allocated
engineobjects. By leveragingguard mallocwith thepre-scribbleoption, it was observed that the six high bytes of a specific offset (0x68) within these objects were not properly zeroed out, retaining previous heap contents (e.g.,0xAAbytes). This uninitialized memory played a crucial role in crafting a reliable exploit chain by allowing the reuse of previously sprayed data.
- Successful Sandbox Escape and Privilege Escalation: The chained vulnerabilities (type confusion + uninitialized memory) were successfully exploited on Intel Macs to achieve a sandbox escape and privilege escalation. The exploit demonstrated the ability to write to restricted directories controlled by the
coreaudioduser, effectively bypassing the sandbox boundaries. Franke noted that Pointer Authentication Codes (PAC) on Apple Silicon would significantly complicate such exploitation.
- Development of a Robust Fuzzing Harness and Methodology: Beyond the specific vulnerabilities, the research yielded a sophisticated fuzzing harness and an iterative methodology tailored for Mach message IPC. This included techniques for direct handler invocation, corpus generation via LLDB scripting, structured fuzzing for stateful APIs, and strategic mocking of irrelevant functionalities to enhance fuzzing efficiency and code coverage.
- Bonus Double Free Vulnerability (CVE 202531235): As a testament to the fuzzer's effectiveness, it also identified a double free vulnerability in CoreAudio, tracked as CVE 202531235. This separate finding further underscores the prevalence of memory safety issues in complex system services and was patched in May.
These findings collectively highlight the persistent security challenges within core operating system components and provide a valuable blueprint for advanced vulnerability research on closed-source platforms.
Technical Deep Dive
▶ Watch: Harness iteration: API call chaining (25:00)
The technical journey to exploit CoreAudio began with the meticulous development of a fuzzing harness. Franke opted for a direct harness approach over using the native Mach message API. While the Mach message API would mirror a real-world exploit, it introduced significant performance overhead, potential points of failure involving the kernel and two processes, and—critically—made it difficult to obtain code coverage and attribute crashes to specific inputs due to the separate process spaces. The direct harness, by contrast, involved loading the CoreAudio message handling code directly into the fuzzer's process, enabling faster execution, easier instrumentation, and precise crash attribution.
Identifying the specific Mach message handling function within the closed-source coreaudiod daemon was a key reverse engineering challenge. Initially, searching for the service name (com.apple.audio.coreaudiod) in the coreaudiod binary yielded no direct references. However, it was discovered that the Core Audio framework (a large library) was heavily utilized by the daemon. A unique aspect of modern macOS, starting with Big Sur, is the dYld shared cache, where most framework binaries are not stored as individual files on disk but are bundled together for performance. Franke used third-party extractors or loaded the shared cache directly into IDA Pro (or Binary Ninja/Ghidra) to analyze the Core Audio framework. Within this framework, the bootstrap_check_in call confirmed the correct service registration.
The message handlers themselves are often generated by the Mach Interface Generator (MIG), an interface definition language that abstracts low-level Mach IPC. Franke identified the MIG server subsystem by searching for _subsystem symbols in the dumped Core Audio library. The core message dispatch logic was found to extract a message ID from the incoming message, use it as an index into the MIG subsystem structure, and then call a corresponding function. These RPC functions (message handlers) were conveniently prefixed with __X_, making them identifiable. There were approximately 63 such handlers for CoreAudio.
Calling these handlers directly presented another hurdle: the target symbols were not exported. This precluded standard dlopen/dlsym techniques. Franke leveraged tinyinst, a lightweight dynamic instrumentation framework by Ivon Frick, which can parse Mach-O binary headers and load commands to resolve and call unexported symbols. The full fuzzing harness, which included intricate switch conditions for different message types, was open-sourced on the Project Zero GitHub.
To make the fuzzing effective, a corpus of known good inputs was essential. Franke created an LLDB script to break on the identified MIG handler and dump legitimate Mach messages being sent to CoreAudio. The Audio MIDI Setup tool on macOS proved particularly useful for generating diverse, realistic traffic for this corpus.
The fuzzing itself was performed using Jackaloupe, an excellent fuzzer also by Ivon Frick, prized for its customizability and seamless integration with macOS. Jackaloupe utilized tinyinst for out-of-the-box code coverage, providing crucial feedback on the fuzzer's exploration.
Initial fuzzing quickly produced crashes, but as Franke noted, these are often indicative of fuzzing harness design bugs rather than security vulnerabilities. This led to several critical iterations:
- Proper Target Initialization: The fuzzer initially bypassed crucial bootstrapping and initialization routines that the
coreaudiodbinary would normally perform (e.g., initializing global variables, setting up hardware). This resulted in crashes related to an uninitialized state (e.g., "error there is no system"). Code coverage feedback (green blocks in IDA Pro) helped identify these unexecuted initialization paths, prompting the harness to mimic these setup tasks.
- API Call Chaining (Structured Fuzzing): An early assumption was that message handlers were stateless and independent. However, many APIs are stateful, requiring a specific sequence of calls (e.g., "there is no client" error when trying to set property data without a client). Inspired by Ned Williamson's work, Franke implemented structured fuzzing. Instead of feeding raw bytes directly, the fuzzer's input bytes were consumed to generate a sequence of message IDs. This allowed the fuzzer to explore complex, stateful API call chains, significantly increasing code coverage.
- Mocking Out Functionality: The fuzzer often got stuck exploring irrelevant or problematic functionality. For instance, repeated calls to
bootstrap_check_in(to register the CoreAudio service) after it had already occurred would throw errors. Franke used C function interposing to create custom versions of these functions that simply returnedKERN_SUCCESS, preventing unnecessary errors. Additionally, tinyinst's hook API was used to intercept and bypass non-security-relevant crashes (e.g., a persistent null dereference), improving fuzzing efficiency.
This iterative refinement process ultimately led to the discovery of the type confusion vulnerability. The crash occurred in the XIOContext::fetchWorkgroupPort function, which was shallow in the call stack but involved a virtual function call. Analysis in IDA Pro revealed that the copyObjectByObjectID function took input directly from the fuzzer's message, stored it in the RAX register, and then dereferenced RAX at offset 0x68 to fetch another object. A virtual function call then occurred on this second object. The vulnerability stemmed from the code expecting an IOControl type with a pointer at 0x68 leading to a v-table, but receiving a different object type. This caused the virtual function call to occur on arbitrary, attacker-controlled data, leading to a hijack of control flow.
Demo / Proof of Concept
▶ Watch: Type confusion vulnerability discovery (30:00)
The exploitation of the discovered type confusion vulnerability was a multi-stage process, meticulously crafted to achieve a sandbox escape and privilege escalation on Intel Macs. Franke acknowledged that Apple Silicon with Pointer Authentication Codes (PAC) would significantly complicate this, as return addresses and function pointers are signed.
The initial exploitation strategy aimed to write attacker-controlled data to the crucial offset 0x68 of any HAL object in the linked list. An early attempt involved setting a UID parsed from an incoming message to this offset. However, this proved insufficient because the CFString type used for the UID has an uncontrollable header, and the exploit required offset 0x0 of the object pointed to by 0x68 to be attacker-controlled. The goal was to write a pointer to a controlled object, which in turn would point to further controlled data.
This led to the discovery of an uninitialized memory bug using guard malloc with the pre-scribble option (which fills newly allocated memory with 0xAA bytes). It was found that in engine objects, the six high bytes at offset 0x68 were uninitialized, retaining previous heap contents, while the two low bytes were cleared. This presented an opportunity to reuse previously allocated data.
The refined exploitation strategy involved:
- Allocating an
engineobject. - Heap spraying with attacker-controlled data to create an indirect pointer chain.
- Triggering the uninitialized memory bug to get the program to reuse an indirect pointer from the spray in the
engineobject's uninitialized0x68region. - Leveraging the caveat: The last two bytes of the indirect pointer being zeroed out actually became an advantage. When the stars aligned, this zeroing would cause the
0x68offset to point to theraw bytes pointerof aCFStringobject within the spray, rather than its uncontrollable header.
Finding a reliable way to allocate the engine object was challenging. An initial path created engine objects of 776 bytes, but these fell into the nano and tiny malloc zones on macOS, which are always zeroed before allocation, negating the uninitialized memory bug. A second path created engine objects of 1152 bytes, placing them in the small malloc region where uninitialized memory could persist. While instantiating these normally required root privileges (for audio plugins), CoreAudio naturally creates a few such engine objects at startup. Crucially, system daemons on macOS continually restart, providing unlimited retries for the exploit.
For heap spraying, Franke utilized Property Lists (PLists), a common macOS exploitation primitive. PLists, containing arrays of CFString objects, could be sent to the service. This data would be parsed, stored on the heap, and also persisted to disk, being reloaded each time coreaudiod restarted. CFArray and CFDictionary types were key for creating the nested data structures required for the indirect pointer chain.
The final exploit flow was:
- Call the
setPropertyDataPList API multiple times, sending PLists with arrays ofCFStringobjects to spray the heap. - Trigger the type confusion once to crash
coreaudiod, forcing it to restart and reload the PLists into memory. - Hope that one of the naturally occurring
engineobjects gets allocated over the sprayedCFStringarray. - Trigger the type confusion again on a random
engineobject. - Through repeated attempts (thanks to daemon restarts), the zeroing of the last two bytes of the
0x68offset would eventually align with araw bytes pointerwithin the sprayedCFString, granting control over arbitrary data. - Once control was achieved, a ROP chain was built, starting with a stack pivot gadget, to perform a file open operation on a directory (
/Library/Preferences/Audio) normally writable only by thecoreaudioduser. UTF-16 encoding was used for the filename.
The demo visually confirmed the exploit's success. Initially, a normal user could not create a file in the restricted /Library/Preferences/Audio directory. After running the exploit, which involved multiple restarts and retries to achieve the necessary heap layout, a file was successfully created in that directory, owned by the coreaudiod user, demonstrating a clear sandbox escape and privilege escalation.
Defensive Implications
▶ Watch: Live demo of the sandbox escape exploit (41:00)
The research presented by Dillon Franke offers several crucial defensive implications for developers and security professionals, particularly those working with macOS and iOS:
- Rethink IPC Security: IPC mechanisms like Mach messages are critical attack surfaces for sandbox escapes and privilege escalation. All IPC interfaces, especially those exposed to sandboxed processes or running with elevated privileges, must undergo rigorous security review and fuzzing.
- Prioritize Memory Safety: The type confusion and uninitialized memory bugs highlight the enduring importance of memory safety. Developers should aggressively use modern memory-safe languages where possible, or employ robust static and dynamic analysis tools (like AddressSanitizer, UndefinedBehaviorSanitizer) to catch issues like type confusion, use-after-free, and uninitialized memory reads.
- Embrace Pointer Authentication Codes (PAC): For Apple Silicon, PACs significantly complicate exploitation by signing pointers. Defenders should ensure their applications and system components are designed to fully leverage these hardware-backed security features where available, making ROP chains and arbitrary pointer manipulation much harder.
- Thorough Initialization Routines: The need for proper target initialization in the fuzzing harness underscores that incomplete or incorrect object/system initialization can lead to exploitable states. All global variables, hardware components, and object states must be correctly initialized before processing untrusted input.
- Design for Statelessness or Secure State Management: The discovery of API call chaining issues emphasizes the complexity of stateful APIs. Where possible, APIs should be designed to be stateless. If state is necessary, ensure that state transitions are strictly validated, and that improper sequencing of calls cannot lead to an exploitable condition.
- Continuous Fuzzing and Code Coverage: Knowledge-driven fuzzing, as demonstrated, is a powerful technique for uncovering deep vulnerabilities in closed-source code. Organizations should integrate continuous, coverage-guided fuzzing into their development lifecycle for critical system components, iterating on harnesses based on code coverage feedback.
- Review System Daemon Privileges: System daemons often run with elevated privileges. Regular audits of their exposed services and their minimum required privileges are essential. Reducing the attack surface and privilege level of these components can significantly mitigate the impact of a successful exploit.
- Secure Heap Management: The reliance on heap spraying and uninitialized memory reuse indicates that robust heap sanitization and allocation strategies are vital. Features like
malloc zoneswith zeroing for smaller allocations are beneficial, but larger allocations also need careful handling to prevent information leaks or control flow hijacking via stale data.
Key Takeaways
- IPC is a Critical Attack Vector: Interprocess Communication (IPC), particularly Mach messages on Apple platforms, remains a primary target for sandbox escapes and privilege escalation due to its role as a bridge between restricted and privileged processes.
- Knowledge-Driven Fuzzing Excels: Combining automated fuzzing with deep manual analysis (knowledge-driven fuzzing) is highly effective for discovering complex vulnerabilities in closed-source, stateful systems like CoreAudio.
- Harness Iteration is Key: Developing a robust fuzzing harness requires iterative refinement, including proper target initialization, structured fuzzing for stateful APIs, and strategic mocking of irrelevant functionality to improve code coverage and reduce noise.
- Memory Safety Bugs Persist: Type confusion and uninitialized memory vulnerabilities continue to be potent primitives for exploitation, even in mature operating system components.
- Apple Silicon Security is Stronger: Hardware-backed defenses like Pointer Authentication Codes (PAC) on Apple Silicon significantly raise the bar for exploitation, making Intel Macs a comparatively easier target for certain attack classes.
- Daemon Persistence Aids Exploitation: The automatic restart of system daemons provides attackers with unlimited retries to achieve complex heap layouts and exploit conditions that might otherwise be unreliable.
About the Speaker(s)
Dillon Franke is a Senior Security Engineer on the Information Security Engineering (ISC) team at Google. In this role, he performs product security reviews on various Google products. Additionally, he dedicates 20% of his time to research with Google Project Zero, focusing on discovering and exploiting zero-day vulnerabilities, primarily within the Apple ecosystem. Prior to his current position, Franke worked at Mandiant, where he was part of their red team, conducting application security penetration testing, source code reviews, and embedded device assessments. He also contributed to Mandiant's Flare team, specializing in malware analysis and tracking in-the-wild exploitation of zero-day vulnerabilities.
Reviews
Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT
Solid end-to-end Mach IPC exploitation research from a Project Zero researcher with real CVEs to show for it. The methodology walkthrough is genuinely useful for anyone fuzzing closed-source Apple components, and the type confusion → uninitialized memory chain is clean. Not a novel attack class, but executed well and taught well.
Heather Calloway (CISO) — STRONG ACCEPT
This is the kind of research CISOs with Apple fleets need to know exists. A Project Zero researcher demonstrates a full sandbox escape chain against coreaudiod on macOS/iOS — type confusion plus uninitialized memory, exploited to privilege escalation. The strategic implication is clear: your high-value targets on Intel Macs are more exposed than you thought, and your patching SLA for Apple system daemons needs teeth.