The full paper, slides from my S&P talk, and all our experiment data can be found at the Fractal project website here: https://fractal-os.com
We've been building Fractal internally for a very long time (first commit was almost exactly 2 years ago), so it's exciting to finally share it with the world. Let me know what you think!
Personally, I learned programming when I was a kid by watching YouTube tutorials + reading random Internet sources. When helping build SHD, it was important to me that we "paid it forward" & made all our lab materials open for everyone to learn from.
Our labs include building your own real spectre attack against the kernel, bypassing ASLR and building ROP chains with various side channels, finding and exploiting backdoors in a RISC-V CPU by building a hardware fuzzer, and more.
(source: I designed the Spectre lab plus a few others)
If you give them a try, please do let us know what you think! We genuinely want these activities to be fun and approachable (we designed them like a big CTF) and welcome feedback from the community.
Unwinding changes to the TLB on every mispredict would have a significant overhead and hurt overall performance. Removing valid data you just cached (speculatively or otherwise) is generally a bad idea.
User mode software requires a TLB (unless you want to do a page walk for every single instruction!)
Even if you could remove the TLB entirely from the CPU somehow, the attacker could just use the cache or some other microarchitectural structure.
Additionally, if can find a way to trick a user into installing a malicious kext, why even bother with PACMAN? You already have arbitrary kernel code execution!
You could maybe do it with lots of fences or just a ridiculous chain of NOPs after each branch such that the ROB is cleared before you have time to try to load a pointer speculatively.
In practice, both of these would probably kill performance, so I don't think either of these are great solutions. Recall we are targeting the kernel where everything needs to be as fast as possible.
1) Our attack does apply a brute force technique with the twist that crashes are suppressed via speculative execution. If you tried to brute force a PAC against the kernel, you'd instantly panic your device and have to reboot.
2) Given that we never sign anything (only try to verify a signed pointer), and that every authentication attempt happens under speculation, I'm not sure how you would rate limit this without absolutely destroying performance. Keep in mind the kernel is doing a whole lot more with PAC than just our attack (for example, every function's return address is also signed with PAC) so distinguishing valid uses from a PACMAN attack might be challenging.
I suppose you could track how many speculative PAC exceptions you got, but it's a little late to add that now isn't it? And it could also raise lots of false positives due to type confusion style mechanisms on valid mispredicted paths.
This is a great question! What this means is that a software patch cannot fix the speculative execution behavior that causes the PACMAN issue since it is built directly into how the hardware operates.
You can think of it a lot like that! PAC is more advanced as you can describe what a pointer "should" do on access (aka is this a data or code pointer?).
Hi! This is an interesting idea. However, there is a problem that arises- if you rotate the key, then old pointers now become invalid. And since the kernel is always alive and servicing requests (and contains structures with very long lifetimes) we don't believe this to be a practical solution.
Our goal is to demonstrate that we can learn the PAC for a kernel pointer from userspace. Just demonstrating that this is even possible is a big step in understanding of how mitigations like pointer authentication can be thought of in the spectre era.
We do not aim to be a zero day, but instead aim to be a way of thinking about attacks/ an attack methodology.
The timer used in the attack does not require a kext (we just use the kext for doing reverse engineering) but the attack itself never uses the kext timer. All of the attack logic lives in userspace.
Provided the attacker finds a suitable PACMAN Gadget in the kernel (and the requisite memory corruption bug), they can conduct our entire attack from userspace with our multithread timer. You are correct that the PACMAN Gadget we demonstrate in the paper does live in a kext we created, however, we believe PACMAN Gadgets are readily available for a determined attacker (our static analysis tool found 55,159 potential spots that could be turned into PACMAN Gadgets inside the 12.2.1 kernel).