XNU VM copy-on-write bypass due to incorrect shadow creation logic during unaligned vm_map_copy operations [CVE-2022-46689]

We discussed this vulnerability during Episode 180 on 17 January 2023

Kinda of a cool race condition and sort of differential attack deep inside XNU’s virtual memory system that allows for bypassing “copy on write” and writing to the underlying page without making a copy.

This starts off with the vm_map_copy_overwrite function, when handling large copies it will take one of two routes, an aligned or unaligned route, aligned if the copy neatly lands on a page boundary, unaligned if it doesn’t. While these two should semantically do the same thing, the code for an unaligned copy has one extra condition. The aligned copy, if its a copy on write page, always makes a shadow copy of the memory that’ll be used. The unaligned copy how performs the same check for copy on write protected pages, but also checks the page’s flags for the VM_PROT_WRITE flag, only making a shadow copy if the page is also writable.

This condition is enforced earlier in the chain, before the call to perform the copy vm_map_copy_overwrite_nested will iterate over the entire destination address range and ensure they all have the write flag, so this exploitable condition should be possible. However all this isn’t atomic, and there is a race condition. During the copying process the mapping is unlocked and relocked between calls to vm_fault_copy creating an opportunity for the flag to be flipped.

The end result of this is a write to a CoW page that will be reflected in all other users of that same page.