When Queues Become Vulnerabilities: Reverse Engineering GCD, XPC Races, and macOS Detection
Olivia Gallucci (Security Engineer · Datadog)
Black Hat USA 2026 · Day 2 · Briefings
Overview
In this Black Hat USA talk, Olivia Gallucci, a Security Engineer at Datadog, meticulously dissects how the misuse of Apple's Grand Central Dispatch (GCD) framework can introduce critical race conditions and other concurrency vulnerabilities into macOS system services. The presentation highlights that what might appear as mere reliability bugs in typical applications can escalate into significant security flaws when present in privileged system daemons, potentially leading to arbitrary code execution in a root context. Gallucci provides a comprehensive guide for both vulnerability researchers and detection engineers, emphasizing the need to understand the underlying mechanics of concurrency, queue management, and synchronization within the macOS ecosystem.
Key moments
- 0:00 Introduction to processes, threads, and execution
- 2:15 Concurrency, parallelism, and Grand Central Dispatch (GCD)
- 3:15 Understanding GCD dispatch queues and Quality of Service (QoS)
- 4:00 How QoS affects scheduling and creates race conditions
- 5:00 Priority inversion vulnerability explained with a clear analogy
- 6:00 Darwin scheduler behavior and correct synchronization primitives
When Queues Become Vulnerabilities: Reverse Engineering GCD, XPC Races, and macOS Detection
Speakers: Olivia Gallucci, Security Engineer, Datadog
Conference: Black Hat USA
YouTube: https://www.youtube.com/watch?v=x6vr4GWToYc
Overview
In this Black Hat USA talk, Olivia Gallucci, a Security Engineer at Datadog, meticulously dissects how the misuse of Apple's Grand Central Dispatch (GCD) framework can introduce critical race conditions and other concurrency vulnerabilities into macOS system services. The presentation highlights that what might appear as mere reliability bugs in typical applications can escalate into significant security flaws when present in privileged system daemons, potentially leading to arbitrary code execution in a root context. Gallucci provides a comprehensive guide for both vulnerability researchers and detection engineers, emphasizing the need to understand the underlying mechanics of concurrency, queue management, and synchronization within the macOS ecosystem.
The talk delves into the intricacies of processes, threads, concurrency, and parallelism, laying a foundational understanding before exploring how GCD's queue semantics and Quality of Service (QoS) choices can create temporal vulnerabilities. Gallucci powerfully demonstrates this by referencing a famous 2018 CVE in the com.apple.gsscred XPC service, where a subtle queue misconfiguration opened a critical race window. Ultimately, the session equips attendees with actionable strategies for static code review, telemetry analysis, and behavioral detection to identify and mitigate such sophisticated concurrency-related security risks on macOS.
Background
▶ Watch: Introduction to processes, threads, and execution (0:00)
To appreciate the nuances of concurrency vulnerabilities, it's essential to first grasp fundamental operating system concepts. A process serves as a container for resources like virtual memory and descriptors, while threads are the actual runnable entities within that process. Concurrency is the system's ability to make progress on multiple tasks by overlapping or interleaving their execution, even on a single core. This can lead to interleavings, which are different possible execution orders of operations from multiple threads accessing shared resources, often resulting in non-deterministic behavior. Parallelism, in contrast, involves executing multiple tasks simultaneously on multiple cores. While concurrency improves responsiveness, parallelism is crucial for how GCD scales execution, and how this scaling can introduce problems like thread overcommitment and the interleaving of privileged and unprivileged operations.
At the heart of Apple's concurrency model is Grand Central Dispatch (GCD), a system library and framework designed to manage task queues and execution without requiring explicit thread management by developers. GCD abstracts thread management, allowing developers to enqueue blocks of work onto dispatch queues. These queues come in two primary types: serial queues, which ensure tasks run one at a time in the order received, and concurrent queues, which permit multiple tasks to execute simultaneously, managed by the system scheduler. Crucially, GCD employs Quality of Service (QoS) classes to prioritize tasks, influencing scheduling priority and resource allocation. Misconfigurations of QoS can lead to high-priority operations being delayed, creating exploitable timing windows.
Gallucci outlines several specific concurrency issues that GCD, if misused, can facilitate:
- Race Conditions: Occur when two or more executions access a shared state without proper synchronization, causing outcomes to vary based on scheduling interleavings. This also encompasses Time-of-Check-Time-of-Use (TOCTTOU) vulnerabilities. GCD does not automatically prevent these; correct queue usage and serialization are paramount.
- Priority Inversion: Happens when a high-priority task becomes blocked, waiting for a low-priority task to complete. On Darwin, the scheduler can indefinitely preempt low-cost threads, potentially leading to deadlocks if a low-priority thread holds a critical resource (like a lock) and never gets scheduled to release it. Apple's kernel provides priority inheritance in certain synchronization primitives like mutexes and OS unfair locks, which temporarily boost the low-cost thread's priority. However, more complex locks like reader/writer locks, semaphores, or custom implementations often lack this feature. The misuse of dispatch semaphores and spin locks (which busy-wait) is specifically identified as the "semaphore anti-pattern," a common source of priority inversion issues on macOS, as they don't carry ownership information, preventing the scheduler from boosting the waiting thread. Developers can observe these using Xcode's thread performance checker.
- Dispatch Sync Deadlocks: Occur when
dispatch_syncis used on the same serial queue that the current thread is already executing on, causing the thread to wait for itself and leading to an instant application freeze. This is particularly dangerous for system services where a listener queue might try to call back into itself synchronously. Apple's documentation explicitly warns against this, and the correct approach is typicallydispatch_asyncor code restructuring to avoid synchronous self-blocking. - Resource Starvation via Worker Thread Busyness: Flooding a concurrent queue with too many unfinished tasks can exhaust GCD's underlying thread pool, leading to thread pool starvation or saturation. This can manifest as high thread churn or CPU spikes. Early GCD documentation promised smart thread limiting, but pathological cases can lead to thread explosion, where
libdispatchspawns dozens or even hundreds of threads to break stalemates when existing threads are blocked. This not only hurts performance but can starve other system components of CPU time. Apple has learned from these experiences, as evidenced by the abandonment of thesecurity transformsAPI in Mac OS 10.7 (which created a new queue and thread per task) and the rewriting of many macOS daemons in iOS 12 to be single-threaded for performance.
Key Findings
▶ Watch: Understanding GCD dispatch queues and Quality of Service (QoS) (3:15)
The central finding of this talk is that implicit threading assumptions in privileged macOS services, particularly those exposed via XPC, are inherently unsafe and can transform seemingly innocuous concurrency bugs into critical security vulnerabilities. When GCD's queue configuration is mistaken, a service designed to process requests serially can inadvertently handle them concurrently. This creates exploitable race windows that an unprivileged client can reliably hit. The consequence, as demonstrated by the GSS Cred XPC service vulnerability, can be memory corruption and arbitrary code execution within a highly privileged (root) context, effectively bypassing macOS's robust sandboxing mechanisms. The talk underscores that such architectural flaws, manifesting through unmanaged concurrent paths or unsynchronized mutable states, represent significant targets for privilege escalation and sandbox escapes.
Technical Deep Dive
▶ Watch: How QoS affects scheduling and creates race conditions (4:00)
The most illustrative example of GCD misuse leading to a critical security vulnerability on macOS is the CVE discovered by Brandon Azad in 2018 within the com.apple.gsscred XPC service. The com.apple.gsscred daemon is a built-in macOS system service responsible for managing Generic Security Services (GSS) credentials, commonly used for Kerberos or enterprise Single Sign-On (SSO) tickets. These bundle identifiers, like com.apple.gsscred, are crucial for macOS to label and route applications and services, appearing in logs, entitlements, and permission decisions, including the Transparency, Consent, and Control (TCC) database.
Azad's vulnerability was a high-impact race condition that allowed an unprivileged process to trigger a memory corruption condition in this privileged root service. The root cause was a fundamental misconfiguration in how the XPC service handled incoming client connections. While the service instantiated a serial dispatch queue for events, it critically failed to bind this queue to the incoming client connections using XPC connection at target queue. As a result, message handlers, instead of executing serially as intended, defaulted to a concurrent queue. This architectural oversight completely destroyed the expected serialization guarantees.
The shift to concurrent execution created a use-after-free race condition. With multiple threads processing requests simultaneously, it became possible for one thread to deallocate a GSS credential object while another thread was still actively using it. Azad precisely weaponized this timing window to corrupt memory, ultimately achieving arbitrary code execution within the root context of the com.apple.gsscred service.
This incident served as a stark demonstration that:
- Implicit threading assumptions are critically unsafe in privileged code.
- Race windows can be exploited without requiring kernel compromise.
- XPC services must explicitly enforce serialization to prevent user-space race conditions from escalating into system-level breaches.
The vulnerability highlights the critical role of XPC in macOS security. XPC encapsulates macOS Inter-Process Communication (IPC) and is a primary mechanism for sandboxed client applications to interact with privileged system daemons. A vulnerability in an XPC service running as root or with elevated entitlements can act as a sandbox escape vector, allowing unprivileged code to gain privileged access and undermine the endpoint's security model. Therefore, understanding the concurrency model and queueing choices within XPC service handlers is paramount for identifying and mitigating privilege escalation risks on macOS.
Demo / Proof of Concept
▶ Watch: Priority inversion vulnerability explained with a clear analogy (5:00)
While Olivia Gallucci's talk does not feature a live demonstration or a novel proof-of-concept exploit, it extensively references the highly impactful 2018 com.apple.gsscred CVE as a concrete example of the vulnerabilities discussed. This historical exploit serves as the primary "proof of concept" for how queue misconfigurations in GCD can lead to severe security breaches in privileged macOS services.
For developers and researchers looking to observe concurrency issues, Gallucci highlights Xcode's thread performance checker. This runtime tool can detect priority inversions in real-time, logging warnings when a high-cost thread waits on a lower-cost thread. It also flags non-UI work running on the main thread, providing a practical way to identify potential issues early in the development or research phase, even if reproducibility of actual exploits can be "shaky" due to kernel band-aids.
Defensive Implications
▶ Watch: Darwin scheduler behavior and correct synchronization primitives (6:00)
Understanding how GCD misuse leads to vulnerabilities is only half the battle; the other half is implementing effective defensive strategies. Gallucci outlines a three-pronged approach encompassing static review, telemetry analysis, and behavioral detection.
Static Review Patterns
Static code analysis and manual code reviews are crucial for identifying architectural flaws before deployment. Key patterns to flag include:
- XPC Connection Queuing: When a daemon accepts a new XPC connection, it's critical to verify that
XPC connection at target queueis explicitly called. Failure to do so means message handlers may execute on an unintended concurrent queue, immediately exposing the service to race conditions. This is a strong, easily codifiable signal for potential race exposure in privileged services. - Serial vs. Concurrent Execution Assumptions: Code that implicitly depends on requests arriving one at a time is highly vulnerable, especially around authorization state, object lifecycle management, or shared caches. XPC clients can easily generate parallel pressure. Any logic relying on ordering guarantees that are not explicitly enforced by synchronization primitives or serial queues is a high-value finding.
- Synchronous Calls (especially
dispatch_sync): The use ofdispatch_syncin a privileged daemon should be scrutinized or require explicit documentation. While not every synchronous dispatch is inherently wrong, it often indicates blocking behavior, carries lock inversion risks, and can lead to deadlocks under load or adversarial timing. These constructs might pass happy-path testing but fail under stress. - Shared Mutable State Without Synchronization: Identify global singleton state or shared objects accessed from multiple handlers without proper synchronization mechanisms (e.g., locks, atomics, or a dedicated serial queue funnel). This is a common root cause of timing-dependent flaws and prevents both reliability defects and exploit primitives.
Telemetry Signals
Post-deployment, telemetry provides visibility into operational risks, signaling when weak points are being stressed.
- Crash Patterns: Repeated crashes, assertions, or guard failures within a privileged daemon, particularly in timing-sensitive code paths, are major indicators. While an isolated crash might be a stability bug, a repeated pattern, especially around state transitions, cleanup paths, or request handling boundaries, strongly suggests an active attempt to hit a race window.
- Thread Churn Spikes: An unusual number of threads being created by a daemon, or sharp changes in queue drain behavior, indicates the service is under concurrency stress it wasn't designed for. Attackers probing race windows often generate this exact kind of telemetry, making it a valuable signal for detection even when not explicitly malicious.
- Queuing Backlogs: Long wait times on dispatch queues, heavy synchronous waits, or evidence of work piling up faster than it drains are all useful indicators. These often appear before a visible crash and can suggest deadlocks, priority inversion, or lock contention, enabling earlier detection of unsafe code paths or exploitation attempts.
Behavioral Detection
This layer focuses on identifying abnormal or adversarial stress patterns.
- Frequent Thread Creation Spikes Relative to Baseline: Instead of absolute volume, focus on relative deviation from a process's normal profile. This makes detections more robust and reduces false positives, as some daemons are naturally noisy.
- Rate Limiting XPC Invocations: While potentially controversial, if a client issues many parallel requests into a privileged service, it might be probing for race windows. This is particularly suspicious if request volume and concurrency are high, and the target daemon normally expects low to moderate parallelism. Even if not immediately blocked, such activity should be logged, scored, and correlated with crashes or queuing delays.
- Queue Drain Time Anomalies: Elevated synchronization wait times are a strong sign of deadlocks, lock contention, or scheduling inversion. This is a prime example of how performance telemetry can double as security telemetry, helping threat detection engineers identify adversarial timing behaviors or vulnerable code.
In summary, the proposed defensive model is straightforward: static reviews pinpoint likely race conditions, telemetry reveals when those weaknesses are stressed, and behavioral detections highlight abnormal or adversarial stress patterns. By combining these approaches, organizations can proactively identify and mitigate exploit opportunities in privileged macOS services.
Key Takeaways
- Race Conditions as Security Vulnerabilities: On macOS, what appear as reliability bugs in concurrency can become critical security problems when present in privileged system services, potentially leading to privilege escalation and sandbox escapes.
- GCD Misuse is a Primary Vector: Misconfigurations in Apple's Grand Central Dispatch (GCD) framework, particularly regarding queue types (serial vs. concurrent) and Quality of Service (QoS) choices, are common root causes for exploitable race conditions.
- Implicit Assumptions are Dangerous: Privileged XPC services often implicitly assume a single-threaded execution model, but clients can easily create parallel pressure. Explicitly enforcing serialization and synchronizing mutable state are crucial.
- The GSS Cred CVE as a Blueprint: The 2018
com.apple.gsscredvulnerability (CVE) serves as a canonical example where a missing target queue configuration in an XPC service led to a use-after-free race condition and root arbitrary code execution. - Multi-Layered Detection is Essential: Effective defense requires a combination of static code review (identifying unsafe queuing patterns, synchronous calls, and unsynchronized shared state), telemetry analysis (monitoring for crashes, thread churn spikes, and queuing backlogs), and behavioral detection (flagging anomalous thread creation or XPC invocation rates).
- Performance Telemetry is Security Telemetry: Metrics like queue drain times and synchronization wait times, typically used for performance monitoring, can also be powerful indicators of adversarial timing behaviors or underlying concurrency vulnerabilities.
About the Speaker(s)
Olivia Gallucci is a Security Engineer at Datadog. A recent graduate at the time of this Black Hat USA presentation, she brings a focused perspective to macOS security, particularly in the realm of concurrency and race conditions. Her work extends beyond conference talks; she has authored a blog post specifically on TOCTTOU attacks on macOS and discussed related topics on a podcast episode with Hackers on the Rocks. Gallucci also maintains a newsletter called "read to read," which focuses on Apple security research and insights, typically posting monthly. Her expertise lies in reverse engineering, vulnerability research, and detection engineering within the macOS ecosystem.
Reviews
Dr. Zero (Offensive Security Researcher) — SOLID
A competent primer on GCD concurrency bugs and their security implications, anchored by a well-chosen historical CVE. Good for detection engineers new to macOS internals, but no original research — this is synthesis and pedagogy, not discovery.
Heather Calloway (CISO) — STRONG ACCEPT
This is a solid practitioner-level talk for anyone running detection engineering or threat research on macOS endpoints. Gallucci walks through a real bug class with real telemetry implications. Not flashy, but operationally useful.