macOS Kernel & System Extensions

XNU Kernel

The core of macOS is XNU, which stands for "X is Not Unix". This kernel is fundamentally composed of the Mach microkernel (to be discussed later), and elements from Berkeley Software Distribution (BSD). XNU also provides a platform for kernel drivers via a system called the I/O Kit. The XNU kernel is part of the Darwin open source project, which means its source code is freely accessible.
From a perspective of a security researcher or a Unix developer, macOS can feel quite similar to a FreeBSD system with an elegant GUI and a host of custom applications. Most applications developed for BSD will compile and run on macOS without needing modifications, as the command-line tools familiar to Unix users are all present in macOS. However, because the XNU kernel incorporates Mach, there are some significant differences between a traditional Unix-like system and macOS, and these differences might cause potential issues or provide unique advantages.
Open source version of XNU:


Mach is a microkernel designed to be UNIX-compatible. One of its key design principles was to minimize the amount of code running in the kernel space and instead allow many typical kernel functions, such as file system, networking, and I/O, to run as user-level tasks.
In XNU, Mach is responsible for many of the critical low-level operations a kernel typically handles, such as processor scheduling, multitasking, and virtual memory management.


The XNU kernel also incorporates a significant amount of code derived from the FreeBSD project. This code runs as part of the kernel along with Mach, in the same address space. However, the FreeBSD code within XNU may differ substantially from the original FreeBSD code because modifications were required to ensure its compatibility with Mach. FreeBSD contributes to many kernel operations including:
  • Process management
  • Signal handling
  • Basic security mechanisms, including user and group management
  • System call infrastructure
  • TCP/IP stack and sockets
  • Firewall and packet filtering
Understanding the interaction between BSD and Mach can be complex, due to their different conceptual frameworks. For instance, BSD uses processes as its fundamental executing unit, while Mach operates based on threads. This discrepancy is reconciled in XNU by associating each BSD process with a Mach task that contains exactly one Mach thread. When BSD's fork() system call is used, the BSD code within the kernel uses Mach functions to create a task and a thread structure.
Moreover, Mach and BSD each maintain different security models: Mach's security model is based on port rights, whereas BSD's security model operates based on process ownership. Disparities between these two models have occasionally resulted in local privilege-escalation vulnerabilities. Apart from typical system calls, there are also Mach traps that allow user-space programs to interact with the kernel. These different elements together form the multifaceted, hybrid architecture of the macOS kernel.

I/O Kit - Drivers

I/O Kit is the open-source, object-oriented, device-driver framework in the XNU kernel and is responsible for the addition and management of dynamically loaded device drivers. These drivers allow for modular code to be added to the kernel dynamically for use with different hardware, for example. They are located in:
  • /System/Library/Extensions
    • KEXT files built into the OS X operating system.
  • /Library/Extensions
    • KEXT files installed by 3rd party software
#Use kextstat to print the loaded drivers
Executing: /usr/bin/kmutil showloaded
No variant specified, falling back to release
Index Refs Address Size Wired Name (Version) UUID <Linked Against>
1 142 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
2 11 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
3 170 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
4 0 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
5 175 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
6 154 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
7 88 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
8 106 0 0 0 (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
9 2 0xffffff8003317000 0xe000 0xe000 (1) 6C1342CC-1D74-3D0F-BC43-97D5AD38200A <5>
10 12 0xffffff8003544000 0x92000 0x92000 (11.1) F5F1255F-6552-3CF4-A9DB-D60EFDEB4A9A <8 7 6 5 3 1>
Until the number 9 the listed drivers are loaded in the address 0. This means that those aren't real drivers but part of the kernel and they cannot be unloaded.
In order to find specific extensions you can use:
kextfind -bundle-id #Search by full bundle-id
kextfind -bundle-id -substring IOR #Search by substring in bundle-id
To load and unload kernel extensions do:

IPC - Inter Process Communication

macOS Kernel Extensions

macOS is super restrictive to load Kernel Extensions (.kext) because of the high privileges that code will run with. Actually, by default is virtually impossible (unless a bypass is found).

macOS System Extensions

Instead of using Kernel Extensions macOS created the System Extensions, which offers in user level APIs to interact with the kernel. This way, developers can avoid to use kernel extensions.