int minherit(__unused proc_t p, struct minherit_args *uap, __unused register_t *retval) { mach_vm_offset_t addr; mach_vm_size_t size; register vm_inherit_t inherit; vm_map_t user_map; kern_return_t result; AUDIT_ARG(addr, uap->addr); AUDIT_ARG(len, uap->len); AUDIT_ARG(value, uap->inherit); addr = (mach_vm_offset_t)uap->addr; size = (mach_vm_size_t)uap->len; inherit = uap->inherit; user_map = current_map(); result = mach_vm_inherit(user_map, addr, size, inherit); switch (result) { case KERN_SUCCESS: return (0); case KERN_PROTECTION_FAILURE: return (EACCES); } return (EINVAL); }
int main(void) { kern_return_t kr; int status; mach_port_t mytask = mach_task_self(); mach_vm_size_t size = (mach_vm_size_t)vm_page_size; kr = mach_vm_allocate(mytask, &page_shared, size, VM_FLAGS_ANYWHERE); OUT_ON_MACH_ERROR("vm_allocate", kr); kr = mach_vm_allocate(mytask, &page_cow, size, VM_FLAGS_ANYWHERE); OUT_ON_MACH_ERROR("vm_allocate", kr); kr = mach_vm_inherit(mytask, page_shared, size, VM_INHERIT_SHARE); OUT_ON_MACH_ERROR("vm_inherit(VM_INHERIT_SHARE)", kr); kr = mach_vm_inherit(mytask, page_cow, size, VM_INHERIT_COPY); OUT_ON_MACH_ERROR("vm_inherit(VM_INHERIT_COPY)", kr); FIRST_UINT32(page_shared) = (unsigned int)0xAAAAAAAA; FIRST_UINT32(page_cow) = (unsigned int)0xBBBBBBBB; printf("%-12s%-8s%-10s%-12s%-10s%s\n", "Process", "Page", "Contents", "VM Object", "Refcount", "Event"); peek_at_some_memory("parent", "before forking"); if (fork() == 0) child_process(); // this will also exit the child wait(&status); peek_at_some_memory("parent", "after child is done"); out: mach_vm_deallocate(mytask, page_shared, size); mach_vm_deallocate(mytask, page_cow, size); exit(0); }