Q1: How does the vm_object_t hierarchy differ between MAP_SHARED and MAP_PRIVATE?

vm_object_t hierarchy of MAP_SHARED:
MAP_SHARED

vm_object_t hierarchy of MAP_PRIVATE:
MAP_PRIVATE

Q2: How is memory data written back to the file?

In fact, the data in memory is not written back to the file.

sudo reboot
hexdump AAAAs.txt

You will see that the file content has not changed.

After unwire_mlock_poc exits, the vnode_t corresponding to AAAAs.txt is not released, will be reused, so modifications can take effect across processes.
It is currently unclear whether this is a memory leak or an intentional optimization.

Q3: Why doesn’t executing munlock first work?

Because the zero_wired_pages flag will be cleared.

file: osfmk/vm/vm_map.c
function: vm_map_unwire_nested

if (entry->zero_wired_pages) {
    entry->zero_wired_pages = FALSE;
}

Q4: How was the vulnerability fixed?

Add permission checks.

ver: xnu-11417.101.15
file: osfmk/vm/vm_map.c
function: vm_map_behavior_set

if (new_behavior == VM_BEHAVIOR_ZERO_WIRED_PAGES) {
    /* zeroing requires write access */
    temp_entry = entry;
    // ...
}

Ref

  • https://project-zero.issues.chromium.org/issues/391518636