Walking Into Guard Pages: A Harness for XNU, and a Pile of Bugs to Follow
Part 0 of up to 15
In 2023 I trained a custom language model on CodeBERT to find bugs in XNU. At the time, grep was still better. Both still have their uses today, and as LLM systems keep improving I expect us to shift back toward more deterministic bug hunts, because we need more confidence in the security of our systems. That doesn't mean we can't get in on the fun in the meantime.
Finding "bugs" has definitely gotten easier. But most vulnerabilities are not actually exploitable, and proving exploitability is real work. Given the glut of AI "finding bugs" that turn out to be invalid or non-existent, what matters now is proving a vulnerability is real and actually reachable. Apple shipped Target Flags a while back, so in August I decided to build a harness and go find some bugs, because why not.
The making of the sausage
Two principles underlay the harness: each task gets exactly one decision, and the more determinism the better.
I wanted something that would take my ideas and validate them. Thinking about ways to break things is a ton of fun, and so is finding creative ways to drive a bug to its limit. Making it reproduce, over and over? That's a job for something that doesn't get bored.
I started with the most annoying part: VM management. I won't bore you with the details, but Apple only lets you run two macOS VMs on a machine at once, which meant building tooling to manage them. Then came the driver. The harness can build the PoCs on the host but can't run them there (thank you, mounts), which makes collecting panic logs more of a pain. Determinism has its costs.
With the VMs out of the way I needed a way to check for duplicates, and that part was straightforward: a hash of the line or address where the bug was found, plus a hash of the function name and line number, dedupes quickly and well enough.
Bugs themselves are always self-contained. Each one comes with a "rigging" that uses the VM tooling to grab a VM, install the PoC, run it to crash, and collect the panic, and ideally the flag, if I hadn't already pushed it to a working exploit. The agent doesn't get to call it either way. A bash script checks that the boot's target flags are in the right registers with the right settings.
For context management, almost everything that mattered came down to not letting tasks pollute each other, so each one only gets what it needs. That's what kept multi-day runs from falling apart.

141 findings in, 17 reports out
The harness proposed 141 findings. I reported 17. The most common ways they died:
- It hallucinated, and the code didn't square with what the model reported.
- A check already prevents the bug, and the model ignored it.
- The math is wrong, with offsets and sizes that don't survive a calculator.
- It assumed semantics that don't hold, like how long an object stays alive or what can run in between. That's where most of the races came from.
- The bug is real, but nothing calls the function, or the only caller is already the kernel.
Anecdotally, findings from binary analysis alone were much less likely to get the math wrong, misread the interface, or turn out unreachable, though my sample size is small.
Does killing 88% of findings hurt? Sure. But I didn't have to do much to get the initial bugs, so it wasn't so bad. Hopefully it gives you some idea of how much noise your friendly bug bounty triager and security engineer is dealing with right now.

The plan
Three CVEs have been assigned to me so far:
| CVE | Component | Class | Platforms in Apple's record |
|---|---|---|---|
| CVE-2026-65350 | Kernel | use-after-free | iOS, iPadOS, macOS, tvOS, visionOS, watchOS |
| CVE-2026-112507 | Kernel | out-of-bounds write | iOS, iPadOS |
| CVE-2026-112524 | udf | use-after-free | macOS |
CVE-2026-112524 and CVE-2026-65350 were also found by others. CVE-2026-112507 was one of the few reports with no collisions. The other 14 reports are still working their way through Apple's system.
One of my first three duped, so extrapolating out, at least 5 of the 17 will be dupes too.
Did your Mac update last week? Follow along to find out why.