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:

  1. Trigger free – object returned to zone
  2. Spray controlled data into the same zone – occupy the freed slot
  3. Use the dangling pointer – access controlled data as if it were the original object
  4. 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:

  1. Heap groom: place the target object right after the vulnerable buffer
  2. Overflow – overwrite important fields of the target object
  3. 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:

  1. Allocate object A in zone X
  2. Free object A (dangling reference remains)
  3. Force zone X to release pages
  4. Allocate object B (different type, same size zone) in the same memory
  5. 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

Resources