xref: /xnu-10002.81.5/tests/vm/vm_test_102067976.c (revision 5e3eaea39dcf651e66cb99ba7d70e32cc4a99587)
1 #include <darwintest.h>
2 
3 #include <stdlib.h>
4 
5 #include <mach/mach_host.h>
6 #include <mach/mach_init.h>
7 #include <mach/mach_port.h>
8 #include <mach/mach_vm.h>
9 #include <mach/vm_map.h>
10 
11 T_GLOBAL_META(
12 	T_META_NAMESPACE("xnu.vm"),
13 	T_META_RADAR_COMPONENT_NAME("xnu"),
14 	T_META_RADAR_COMPONENT_VERSION("VM"));
15 
16 T_DECL(vm_test_102067976, "Test dangling PTE due to mis-aligned memory entry")
17 {
18 	kern_return_t kr;
19 	mach_vm_size_t vm_named_entry_size, vm_map_entry_size;
20 	mach_vm_offset_t vm_named_entry_offset, vm_map_entry_offset;
21 	mach_port_t named_entry;
22 	mach_vm_address_t address;
23 
24 	vm_named_entry_size = 2 * PAGE_SIZE + 1; /* misaligned! */
25 	vm_named_entry_offset = 0;
26 	vm_map_entry_size = 2 * PAGE_SIZE;
27 	vm_map_entry_offset = PAGE_SIZE;
28 
29 	named_entry = MACH_PORT_NULL;
30 	kr = mach_memory_object_memory_entry(mach_host_self(),
31 	    1, (vm_size_t) vm_named_entry_size,
32 	    VM_PROT_READ | VM_PROT_WRITE,
33 	    MEMORY_OBJECT_NULL, &named_entry);
34 	if (kr == MIG_BAD_ID) {
35 		T_FAIL("mach_memory_object_memory_entry() returned MIG_BAD_ID");
36 		return;
37 	}
38 #if __arm64__ && !__LP64__
39 	/*
40 	 * mach_memory_object_memory_entry() is broken on arm64_32.
41 	 */
42 	if (kr == MIG_BAD_ARGUMENTS) {
43 		T_SKIP("mach_memory_object_memory_entry() returned MIG_BAD_ARGUMENTS (because broken on arm64_32)");
44 		return;
45 	}
46 #endif /* __arm64__ && !__LP64__ */
47 	T_ASSERT_MACH_SUCCESS(kr, "mach_memory_object_memory_entry()");
48 	T_QUIET; T_ASSERT_NE(named_entry, MACH_PORT_NULL, "named_entry is not null");
49 
50 	/* map the memory to our space */
51 	address = 0;
52 	kr = mach_vm_map(mach_task_self(),
53 	    &address,
54 	    (-1),                        /* not 0 but rounds up to 0 */
55 	    0,                           /* mask */
56 	    VM_FLAGS_ANYWHERE,
57 	    named_entry,
58 	    vm_map_entry_offset,         /* offset */
59 	    FALSE,                       /* copy */
60 	    VM_PROT_DEFAULT,
61 	    VM_PROT_DEFAULT,
62 	    VM_INHERIT_DEFAULT);
63 	if (kr == KERN_INVALID_ARGUMENT) {
64 		/* no longer vulnerable */
65 		T_PASS("mach_vm_map(size=-1) no longer succeeds");
66 		return;
67 	}
68 	T_ASSERT_MACH_SUCCESS(kr, "mach_vm_map()");
69 
70 	/* fault in last page + dangling one */
71 	memset((char *)address, 'x', vm_map_entry_size);
72 
73 	/* unmap the memory */
74 	kr = mach_vm_deallocate(mach_task_self(), address, vm_map_entry_size);
75 	T_ASSERT_MACH_SUCCESS(kr, "mach_vm_deallocate()");
76 
77 	/* release named entry */
78 	kr = mach_port_deallocate(mach_task_self(), named_entry);
79 	T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate()");
80 
81 	T_PASS("no panic!");
82 }
83