Vulnerability Classes
Understanding common bug classes helps you know what to look for when auditing code, and how to exploit what you find.
1. Use-After-Free (UAF)
Concept: An object is freed but a pointer to it is still used. When the freed memory is reallocated for a different object, using the dangling pointer accesses the new object through the old context.
struct ipc_port *port = ipc_port_alloc();
// ... use port ...
ipc_port_release(port); // port freed
// ... later ...
port->ip_messages; // UAF! port memory may now contain different object
Exploitation:
- Trigger free – object returned to zone
- Spray controlled data into the same zone – occupy the freed slot
- Use the dangling pointer – access controlled data as if it were the original object
- Result: type confusion, controlled reads/writes, code execution
Example: IOKit clientClose() race – close a UserClient in one thread, call an external method in another thread.
2. Heap Buffer Overflow
Concept: Write data past the boundary of an allocated buffer on the heap, corrupting the next object.
char *buf = kalloc(64);
memcpy(buf, user_data, user_size); // If user_size > 64 → overflow!
Exploitation:
- Heap groom: place the target object right after the vulnerable buffer
- Overflow – overwrite important fields of the target object
- Common targets: function pointers, size fields, linked list pointers
3. Type Confusion
Concept: An object is interpreted as a different type. Field X at offset 0x10 in type A has a completely different meaning from field Y at offset 0x10 in type B.
// Type A: field at offset 0x20 is a size field
struct type_a { ...; uint32_t size; ... };
// Type B: field at offset 0x20 is a pointer
struct type_b { ...; void *ptr; ... };
// If a type B object is interpreted as type A:
// "size" = pointer value → huge size → read/write out of bounds
Exploitation via zone transfer:
- Allocate object A in zone X
- Free object A (dangling reference remains)
- Force zone X to release pages
- Allocate object B (different type, same size zone) in the same memory
- Access via dangling reference – type A operations on type B data
4. Integer Overflow
Concept: An arithmetic operation produces a result larger than the storage – wraps around – bypasses size checks.
uint32_t total = count * elem_size; // If count * elem_size > 2^32 → overflow!
char *buf = kalloc(total); // Allocates less than expected
memcpy(buf, data, count * elem_size); // Copies more than allocated → heap overflow
Commonly found in: External method size validation, buffer allocation before copy.
5. Race Condition (TOCTOU)
Concept: Time-of-Check vs Time-of-Use – a condition is checked at time T1 but used at time T2, and the state changes between T1 and T2.
// Thread 1 (kernel):
if (port->ip_object.io_bits & IO_VALID) { // T1: check valid
// ... other thread frees port here ...
use(port); // T2: use freed port!
}
Exploitation:
- Create multiple threads, race to trigger the window between check and use
- Usually requires running the exploit multiple times (probabilistic)
- Deterministic exploits find ways to eliminate the race (e.g., Trigon)
6. Physical Use-After-Free (PUAF)
Concept: A physical page is freed but the virtual mapping still exists.
Process maps VA 0x1000 → PA 0x2000
Kernel bug: frees PA 0x2000 without removing the VA mapping
Kernel allocates PA 0x2000 for a kernel data structure
Process reads/writes VA 0x1000 → reads/writes kernel data!
This is the basis for modern iOS exploits (kfd, Trigon, …).
7. Information Leak
Concept: The kernel exposes internal data (addresses, values) to userspace.
Types:
- Uninitialized heap data: kalloc returns memory with stale data – leaked addresses
- Out-of-bounds read: Read past buffer boundary – leak adjacent object data
- Side channels: Timing differences reveal kernel state
Used for: KASLR bypass (you need to know the kernel base address before exploiting).
Where to Find Bugs
| Vulnerability class | Where to look |
|---|---|
| UAF | IOKit drivers (lifecycle bugs), IPC port handling |
| Heap overflow | External method struct input parsing, memcpy with user-controlled size |
| Type confusion | Zone allocator (cross-zone), MIG message parsing |
| Integer overflow | Size calculations before allocation |
| Race condition | Multi-threaded IOKit method access, concurrent IPC |
| PUAF | VM subsystem (vm_map, pmap interactions) |
| Info leak | IOKit properties, sysctl handlers, uninitialized stack/heap |