xref: /xnu-8020.140.41/tests/vm_test_mach_map.c (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1*27b03b36SApple OSS Distributions /* Mach vm map miscellaneous unit tests
2*27b03b36SApple OSS Distributions  *
3*27b03b36SApple OSS Distributions  * This test program serves to be a regression test suite for legacy
4*27b03b36SApple OSS Distributions  * vm issues, ideally each test will be linked to a radar number and
5*27b03b36SApple OSS Distributions  * perform a set of certain validations.
6*27b03b36SApple OSS Distributions  *
7*27b03b36SApple OSS Distributions  */
8*27b03b36SApple OSS Distributions #include <darwintest.h>
9*27b03b36SApple OSS Distributions 
10*27b03b36SApple OSS Distributions #include <dlfcn.h>
11*27b03b36SApple OSS Distributions #include <errno.h>
12*27b03b36SApple OSS Distributions #include <ptrauth.h>
13*27b03b36SApple OSS Distributions #include <stdio.h>
14*27b03b36SApple OSS Distributions #include <stdlib.h>
15*27b03b36SApple OSS Distributions #include <string.h>
16*27b03b36SApple OSS Distributions #include <time.h>
17*27b03b36SApple OSS Distributions 
18*27b03b36SApple OSS Distributions #include <sys/mman.h>
19*27b03b36SApple OSS Distributions 
20*27b03b36SApple OSS Distributions #include <mach/mach_error.h>
21*27b03b36SApple OSS Distributions #include <mach/mach_init.h>
22*27b03b36SApple OSS Distributions #include <mach/mach_port.h>
23*27b03b36SApple OSS Distributions #include <mach/mach_vm.h>
24*27b03b36SApple OSS Distributions #include <mach/vm_map.h>
25*27b03b36SApple OSS Distributions #include <mach/task.h>
26*27b03b36SApple OSS Distributions #include <mach/task_info.h>
27*27b03b36SApple OSS Distributions #include <mach/shared_region.h>
28*27b03b36SApple OSS Distributions #include <machine/cpu_capabilities.h>
29*27b03b36SApple OSS Distributions 
30*27b03b36SApple OSS Distributions T_GLOBAL_META(
31*27b03b36SApple OSS Distributions 	T_META_NAMESPACE("xnu.vm"),
32*27b03b36SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
33*27b03b36SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("VM"),
34*27b03b36SApple OSS Distributions 	T_META_RUN_CONCURRENTLY(true));
35*27b03b36SApple OSS Distributions 
36*27b03b36SApple OSS Distributions static void
test_memory_entry_tagging(int override_tag)37*27b03b36SApple OSS Distributions test_memory_entry_tagging(int override_tag)
38*27b03b36SApple OSS Distributions {
39*27b03b36SApple OSS Distributions 	int                     pass;
40*27b03b36SApple OSS Distributions 	int                     do_copy;
41*27b03b36SApple OSS Distributions 	kern_return_t           kr;
42*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr_orig, vmaddr_shared, vmaddr_copied;
43*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize_orig, vmsize_shared, vmsize_copied;
44*27b03b36SApple OSS Distributions 	mach_vm_address_t       *vmaddr_ptr;
45*27b03b36SApple OSS Distributions 	mach_vm_size_t          *vmsize_ptr;
46*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr_chunk;
47*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize_chunk;
48*27b03b36SApple OSS Distributions 	mach_vm_offset_t        vmoff;
49*27b03b36SApple OSS Distributions 	mach_port_t             mem_entry_copied, mem_entry_shared;
50*27b03b36SApple OSS Distributions 	mach_port_t             *mem_entry_ptr;
51*27b03b36SApple OSS Distributions 	int                     i;
52*27b03b36SApple OSS Distributions 	vm_region_submap_short_info_data_64_t ri;
53*27b03b36SApple OSS Distributions 	mach_msg_type_number_t  ri_count;
54*27b03b36SApple OSS Distributions 	unsigned int            depth;
55*27b03b36SApple OSS Distributions 	int                     vm_flags;
56*27b03b36SApple OSS Distributions 	int                     expected_tag;
57*27b03b36SApple OSS Distributions 
58*27b03b36SApple OSS Distributions 	vmaddr_copied = 0;
59*27b03b36SApple OSS Distributions 	vmaddr_shared = 0;
60*27b03b36SApple OSS Distributions 	vmsize_copied = 0;
61*27b03b36SApple OSS Distributions 	vmsize_shared = 0;
62*27b03b36SApple OSS Distributions 	vmaddr_chunk = 0;
63*27b03b36SApple OSS Distributions 	vmsize_chunk = 16 * 1024;
64*27b03b36SApple OSS Distributions 	vmaddr_orig = 0;
65*27b03b36SApple OSS Distributions 	vmsize_orig = 3 * vmsize_chunk;
66*27b03b36SApple OSS Distributions 	mem_entry_copied = MACH_PORT_NULL;
67*27b03b36SApple OSS Distributions 	mem_entry_shared = MACH_PORT_NULL;
68*27b03b36SApple OSS Distributions 	pass = 0;
69*27b03b36SApple OSS Distributions 
70*27b03b36SApple OSS Distributions 	vmaddr_orig = 0;
71*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
72*27b03b36SApple OSS Distributions 	    &vmaddr_orig,
73*27b03b36SApple OSS Distributions 	    vmsize_orig,
74*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
75*27b03b36SApple OSS Distributions 	T_QUIET;
76*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "[override_tag:%d] vm_allocate(%lld)",
77*27b03b36SApple OSS Distributions 	    override_tag, vmsize_orig);
78*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
79*27b03b36SApple OSS Distributions 		goto done;
80*27b03b36SApple OSS Distributions 	}
81*27b03b36SApple OSS Distributions 
82*27b03b36SApple OSS Distributions 	for (i = 0; i < vmsize_orig / vmsize_chunk; i++) {
83*27b03b36SApple OSS Distributions 		vmaddr_chunk = vmaddr_orig + (i * vmsize_chunk);
84*27b03b36SApple OSS Distributions 		kr = mach_vm_allocate(mach_task_self(),
85*27b03b36SApple OSS Distributions 		    &vmaddr_chunk,
86*27b03b36SApple OSS Distributions 		    vmsize_chunk,
87*27b03b36SApple OSS Distributions 		    (VM_FLAGS_FIXED |
88*27b03b36SApple OSS Distributions 		    VM_FLAGS_OVERWRITE |
89*27b03b36SApple OSS Distributions 		    VM_MAKE_TAG(100 + i)));
90*27b03b36SApple OSS Distributions 		T_QUIET;
91*27b03b36SApple OSS Distributions 		T_EXPECT_MACH_SUCCESS(kr, "[override_tag:%d] vm_allocate(%lld)",
92*27b03b36SApple OSS Distributions 		    override_tag, vmsize_chunk);
93*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
94*27b03b36SApple OSS Distributions 			goto done;
95*27b03b36SApple OSS Distributions 		}
96*27b03b36SApple OSS Distributions 	}
97*27b03b36SApple OSS Distributions 
98*27b03b36SApple OSS Distributions 	for (vmoff = 0;
99*27b03b36SApple OSS Distributions 	    vmoff < vmsize_orig;
100*27b03b36SApple OSS Distributions 	    vmoff += PAGE_SIZE) {
101*27b03b36SApple OSS Distributions 		*((unsigned char *)(uintptr_t)(vmaddr_orig + vmoff)) = 'x';
102*27b03b36SApple OSS Distributions 	}
103*27b03b36SApple OSS Distributions 
104*27b03b36SApple OSS Distributions 	do_copy = time(NULL) & 1;
105*27b03b36SApple OSS Distributions again:
106*27b03b36SApple OSS Distributions 	*((unsigned char *)(uintptr_t)vmaddr_orig) = 'x';
107*27b03b36SApple OSS Distributions 	if (do_copy) {
108*27b03b36SApple OSS Distributions 		mem_entry_ptr = &mem_entry_copied;
109*27b03b36SApple OSS Distributions 		vmsize_copied = vmsize_orig;
110*27b03b36SApple OSS Distributions 		vmsize_ptr = &vmsize_copied;
111*27b03b36SApple OSS Distributions 		vmaddr_copied = 0;
112*27b03b36SApple OSS Distributions 		vmaddr_ptr = &vmaddr_copied;
113*27b03b36SApple OSS Distributions 		vm_flags = MAP_MEM_VM_COPY;
114*27b03b36SApple OSS Distributions 	} else {
115*27b03b36SApple OSS Distributions 		mem_entry_ptr = &mem_entry_shared;
116*27b03b36SApple OSS Distributions 		vmsize_shared = vmsize_orig;
117*27b03b36SApple OSS Distributions 		vmsize_ptr = &vmsize_shared;
118*27b03b36SApple OSS Distributions 		vmaddr_shared = 0;
119*27b03b36SApple OSS Distributions 		vmaddr_ptr = &vmaddr_shared;
120*27b03b36SApple OSS Distributions 		vm_flags = MAP_MEM_VM_SHARE;
121*27b03b36SApple OSS Distributions 	}
122*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
123*27b03b36SApple OSS Distributions 	    vmsize_ptr,
124*27b03b36SApple OSS Distributions 	    vmaddr_orig,                            /* offset */
125*27b03b36SApple OSS Distributions 	    (vm_flags |
126*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE),
127*27b03b36SApple OSS Distributions 	    mem_entry_ptr,
128*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
129*27b03b36SApple OSS Distributions 	T_QUIET;
130*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "[override_tag:%d][do_copy:%d] mach_make_memory_entry()",
131*27b03b36SApple OSS Distributions 	    override_tag, do_copy);
132*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
133*27b03b36SApple OSS Distributions 		goto done;
134*27b03b36SApple OSS Distributions 	}
135*27b03b36SApple OSS Distributions 	T_QUIET;
136*27b03b36SApple OSS Distributions 	T_EXPECT_EQ(*vmsize_ptr, vmsize_orig, "[override_tag:%d][do_copy:%d] vmsize (0x%llx) != vmsize_orig (0x%llx)",
137*27b03b36SApple OSS Distributions 	    override_tag, do_copy, (uint64_t) *vmsize_ptr, (uint64_t) vmsize_orig);
138*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
139*27b03b36SApple OSS Distributions 		goto done;
140*27b03b36SApple OSS Distributions 	}
141*27b03b36SApple OSS Distributions 	T_QUIET;
142*27b03b36SApple OSS Distributions 	T_EXPECT_NOTNULL(*mem_entry_ptr, "[override_tag:%d][do_copy:%d] mem_entry == 0x%x",
143*27b03b36SApple OSS Distributions 	    override_tag, do_copy, *mem_entry_ptr);
144*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
145*27b03b36SApple OSS Distributions 		goto done;
146*27b03b36SApple OSS Distributions 	}
147*27b03b36SApple OSS Distributions 
148*27b03b36SApple OSS Distributions 	*vmaddr_ptr = 0;
149*27b03b36SApple OSS Distributions 	if (override_tag) {
150*27b03b36SApple OSS Distributions 		vm_flags = VM_MAKE_TAG(200);
151*27b03b36SApple OSS Distributions 	} else {
152*27b03b36SApple OSS Distributions 		vm_flags = 0;
153*27b03b36SApple OSS Distributions 	}
154*27b03b36SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(),
155*27b03b36SApple OSS Distributions 	    vmaddr_ptr,
156*27b03b36SApple OSS Distributions 	    vmsize_orig,
157*27b03b36SApple OSS Distributions 	    0,              /* mask */
158*27b03b36SApple OSS Distributions 	    vm_flags | VM_FLAGS_ANYWHERE,
159*27b03b36SApple OSS Distributions 	    *mem_entry_ptr,
160*27b03b36SApple OSS Distributions 	    0,              /* offset */
161*27b03b36SApple OSS Distributions 	    FALSE,              /* copy */
162*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
163*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
164*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
165*27b03b36SApple OSS Distributions 	T_QUIET;
166*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "[override_tag:%d][do_copy:%d] mach_vm_map()",
167*27b03b36SApple OSS Distributions 	    override_tag, do_copy);
168*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
169*27b03b36SApple OSS Distributions 		goto done;
170*27b03b36SApple OSS Distributions 	}
171*27b03b36SApple OSS Distributions 
172*27b03b36SApple OSS Distributions 	*((unsigned char *)(uintptr_t)vmaddr_orig) = 'X';
173*27b03b36SApple OSS Distributions 	if (*(unsigned char *)(uintptr_t)*vmaddr_ptr == 'X') {
174*27b03b36SApple OSS Distributions 		T_QUIET;
175*27b03b36SApple OSS Distributions 		T_EXPECT_EQ(do_copy, 0, "[override_tag:%d][do_copy:%d] memory shared instead of copied",
176*27b03b36SApple OSS Distributions 		    override_tag, do_copy);
177*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
178*27b03b36SApple OSS Distributions 			goto done;
179*27b03b36SApple OSS Distributions 		}
180*27b03b36SApple OSS Distributions 	} else {
181*27b03b36SApple OSS Distributions 		T_QUIET;
182*27b03b36SApple OSS Distributions 		T_EXPECT_NE(do_copy, 0, "[override_tag:%d][do_copy:%d] memory copied instead of shared",
183*27b03b36SApple OSS Distributions 		    override_tag, do_copy);
184*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
185*27b03b36SApple OSS Distributions 			goto done;
186*27b03b36SApple OSS Distributions 		}
187*27b03b36SApple OSS Distributions 	}
188*27b03b36SApple OSS Distributions 
189*27b03b36SApple OSS Distributions 	for (i = 0; i < vmsize_orig / vmsize_chunk; i++) {
190*27b03b36SApple OSS Distributions 		mach_vm_address_t       vmaddr_info;
191*27b03b36SApple OSS Distributions 		mach_vm_size_t          vmsize_info;
192*27b03b36SApple OSS Distributions 
193*27b03b36SApple OSS Distributions 		vmaddr_info = *vmaddr_ptr + (i * vmsize_chunk);
194*27b03b36SApple OSS Distributions 		vmsize_info = 0;
195*27b03b36SApple OSS Distributions 		depth = 1;
196*27b03b36SApple OSS Distributions 		ri_count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
197*27b03b36SApple OSS Distributions 		kr = mach_vm_region_recurse(mach_task_self(),
198*27b03b36SApple OSS Distributions 		    &vmaddr_info,
199*27b03b36SApple OSS Distributions 		    &vmsize_info,
200*27b03b36SApple OSS Distributions 		    &depth,
201*27b03b36SApple OSS Distributions 		    (vm_region_recurse_info_t) &ri,
202*27b03b36SApple OSS Distributions 		    &ri_count);
203*27b03b36SApple OSS Distributions 		T_QUIET;
204*27b03b36SApple OSS Distributions 		T_EXPECT_MACH_SUCCESS(kr, "[override_tag:%d][do_copy:%d] mach_vm_region_recurse(0x%llx+0x%llx)",
205*27b03b36SApple OSS Distributions 		    override_tag, do_copy, *vmaddr_ptr, i * vmsize_chunk);
206*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
207*27b03b36SApple OSS Distributions 			goto done;
208*27b03b36SApple OSS Distributions 		}
209*27b03b36SApple OSS Distributions 		T_QUIET;
210*27b03b36SApple OSS Distributions 		T_EXPECT_EQ(vmaddr_info, *vmaddr_ptr + (i * vmsize_chunk), "[override_tag:%d][do_copy:%d] mach_vm_region_recurse(0x%llx+0x%llx) returned addr 0x%llx",
211*27b03b36SApple OSS Distributions 		    override_tag, do_copy, *vmaddr_ptr, i * vmsize_chunk, vmaddr_info);
212*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
213*27b03b36SApple OSS Distributions 			goto done;
214*27b03b36SApple OSS Distributions 		}
215*27b03b36SApple OSS Distributions 		T_QUIET;
216*27b03b36SApple OSS Distributions 		T_EXPECT_EQ(vmsize_info, vmsize_chunk, "[override_tag:%d][do_copy:%d] mach_vm_region_recurse(0x%llx+0x%llx) returned size 0x%llx expected 0x%llx",
217*27b03b36SApple OSS Distributions 		    override_tag, do_copy, *vmaddr_ptr, i * vmsize_chunk, vmsize_info, vmsize_chunk);
218*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
219*27b03b36SApple OSS Distributions 			goto done;
220*27b03b36SApple OSS Distributions 		}
221*27b03b36SApple OSS Distributions 		if (override_tag) {
222*27b03b36SApple OSS Distributions 			expected_tag = 200;
223*27b03b36SApple OSS Distributions 		} else {
224*27b03b36SApple OSS Distributions 			expected_tag = 100 + i;
225*27b03b36SApple OSS Distributions 		}
226*27b03b36SApple OSS Distributions 		T_QUIET;
227*27b03b36SApple OSS Distributions 		T_EXPECT_EQ(ri.user_tag, expected_tag, "[override_tag:%d][do_copy:%d] i=%d tag=%d expected %d",
228*27b03b36SApple OSS Distributions 		    override_tag, do_copy, i, ri.user_tag, expected_tag);
229*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
230*27b03b36SApple OSS Distributions 			goto done;
231*27b03b36SApple OSS Distributions 		}
232*27b03b36SApple OSS Distributions 	}
233*27b03b36SApple OSS Distributions 
234*27b03b36SApple OSS Distributions 	if (++pass < 2) {
235*27b03b36SApple OSS Distributions 		do_copy = !do_copy;
236*27b03b36SApple OSS Distributions 		goto again;
237*27b03b36SApple OSS Distributions 	}
238*27b03b36SApple OSS Distributions 
239*27b03b36SApple OSS Distributions done:
240*27b03b36SApple OSS Distributions 	if (vmaddr_orig != 0) {
241*27b03b36SApple OSS Distributions 		mach_vm_deallocate(mach_task_self(),
242*27b03b36SApple OSS Distributions 		    vmaddr_orig,
243*27b03b36SApple OSS Distributions 		    vmsize_orig);
244*27b03b36SApple OSS Distributions 		vmaddr_orig = 0;
245*27b03b36SApple OSS Distributions 		vmsize_orig = 0;
246*27b03b36SApple OSS Distributions 	}
247*27b03b36SApple OSS Distributions 	if (vmaddr_copied != 0) {
248*27b03b36SApple OSS Distributions 		mach_vm_deallocate(mach_task_self(),
249*27b03b36SApple OSS Distributions 		    vmaddr_copied,
250*27b03b36SApple OSS Distributions 		    vmsize_copied);
251*27b03b36SApple OSS Distributions 		vmaddr_copied = 0;
252*27b03b36SApple OSS Distributions 		vmsize_copied = 0;
253*27b03b36SApple OSS Distributions 	}
254*27b03b36SApple OSS Distributions 	if (vmaddr_shared != 0) {
255*27b03b36SApple OSS Distributions 		mach_vm_deallocate(mach_task_self(),
256*27b03b36SApple OSS Distributions 		    vmaddr_shared,
257*27b03b36SApple OSS Distributions 		    vmsize_shared);
258*27b03b36SApple OSS Distributions 		vmaddr_shared = 0;
259*27b03b36SApple OSS Distributions 		vmsize_shared = 0;
260*27b03b36SApple OSS Distributions 	}
261*27b03b36SApple OSS Distributions 	if (mem_entry_copied != MACH_PORT_NULL) {
262*27b03b36SApple OSS Distributions 		mach_port_deallocate(mach_task_self(), mem_entry_copied);
263*27b03b36SApple OSS Distributions 		mem_entry_copied = MACH_PORT_NULL;
264*27b03b36SApple OSS Distributions 	}
265*27b03b36SApple OSS Distributions 	if (mem_entry_shared != MACH_PORT_NULL) {
266*27b03b36SApple OSS Distributions 		mach_port_deallocate(mach_task_self(), mem_entry_shared);
267*27b03b36SApple OSS Distributions 		mem_entry_shared = MACH_PORT_NULL;
268*27b03b36SApple OSS Distributions 	}
269*27b03b36SApple OSS Distributions 
270*27b03b36SApple OSS Distributions 	return;
271*27b03b36SApple OSS Distributions }
272*27b03b36SApple OSS Distributions 
273*27b03b36SApple OSS Distributions static void
test_map_memory_entry(void)274*27b03b36SApple OSS Distributions test_map_memory_entry(void)
275*27b03b36SApple OSS Distributions {
276*27b03b36SApple OSS Distributions 	kern_return_t           kr;
277*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr1, vmaddr2;
278*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize1, vmsize2;
279*27b03b36SApple OSS Distributions 	mach_port_t             mem_entry;
280*27b03b36SApple OSS Distributions 	unsigned char           *cp1, *cp2;
281*27b03b36SApple OSS Distributions 
282*27b03b36SApple OSS Distributions 	vmaddr1 = 0;
283*27b03b36SApple OSS Distributions 	vmsize1 = 0;
284*27b03b36SApple OSS Distributions 	vmaddr2 = 0;
285*27b03b36SApple OSS Distributions 	vmsize2 = 0;
286*27b03b36SApple OSS Distributions 	mem_entry = MACH_PORT_NULL;
287*27b03b36SApple OSS Distributions 
288*27b03b36SApple OSS Distributions 	vmsize1 = 1;
289*27b03b36SApple OSS Distributions 	vmaddr1 = 0;
290*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
291*27b03b36SApple OSS Distributions 	    &vmaddr1,
292*27b03b36SApple OSS Distributions 	    vmsize1,
293*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
294*27b03b36SApple OSS Distributions 	T_QUIET;
295*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "vm_allocate(%lld)", vmsize1);
296*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
297*27b03b36SApple OSS Distributions 		goto done;
298*27b03b36SApple OSS Distributions 	}
299*27b03b36SApple OSS Distributions 
300*27b03b36SApple OSS Distributions 	cp1 = (unsigned char *)(uintptr_t)vmaddr1;
301*27b03b36SApple OSS Distributions 	*cp1 = '1';
302*27b03b36SApple OSS Distributions 
303*27b03b36SApple OSS Distributions 	vmsize2 = 1;
304*27b03b36SApple OSS Distributions 	mem_entry = MACH_PORT_NULL;
305*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
306*27b03b36SApple OSS Distributions 	    &vmsize2,
307*27b03b36SApple OSS Distributions 	    vmaddr1,                            /* offset */
308*27b03b36SApple OSS Distributions 	    (MAP_MEM_VM_COPY |
309*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE),
310*27b03b36SApple OSS Distributions 	    &mem_entry,
311*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
312*27b03b36SApple OSS Distributions 	T_QUIET;
313*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "mach_make_memory_entry()");
314*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
315*27b03b36SApple OSS Distributions 		goto done;
316*27b03b36SApple OSS Distributions 	}
317*27b03b36SApple OSS Distributions 	T_QUIET;
318*27b03b36SApple OSS Distributions 	T_EXPECT_GE(vmsize2, vmsize1, "vmsize2 (0x%llx) < vmsize1 (0x%llx)",
319*27b03b36SApple OSS Distributions 	    (uint64_t) vmsize2, (uint64_t) vmsize1);
320*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
321*27b03b36SApple OSS Distributions 		goto done;
322*27b03b36SApple OSS Distributions 	}
323*27b03b36SApple OSS Distributions 	T_QUIET;
324*27b03b36SApple OSS Distributions 	T_EXPECT_NOTNULL(mem_entry, "mem_entry == 0x%x", mem_entry);
325*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
326*27b03b36SApple OSS Distributions 		goto done;
327*27b03b36SApple OSS Distributions 	}
328*27b03b36SApple OSS Distributions 
329*27b03b36SApple OSS Distributions 	vmaddr2 = 0;
330*27b03b36SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(),
331*27b03b36SApple OSS Distributions 	    &vmaddr2,
332*27b03b36SApple OSS Distributions 	    vmsize2,
333*27b03b36SApple OSS Distributions 	    0,              /* mask */
334*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
335*27b03b36SApple OSS Distributions 	    mem_entry,
336*27b03b36SApple OSS Distributions 	    0,              /* offset */
337*27b03b36SApple OSS Distributions 	    TRUE,              /* copy */
338*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
339*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
340*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
341*27b03b36SApple OSS Distributions 	T_QUIET;
342*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "mach_vm_map()");
343*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
344*27b03b36SApple OSS Distributions 		goto done;
345*27b03b36SApple OSS Distributions 	}
346*27b03b36SApple OSS Distributions 
347*27b03b36SApple OSS Distributions 	cp2 = (unsigned char *)(uintptr_t)vmaddr2;
348*27b03b36SApple OSS Distributions 	T_QUIET;
349*27b03b36SApple OSS Distributions 	T_EXPECT_TRUE(((*cp1 == '1') && (*cp2 == '1')), "*cp1/*cp2 0x%x/0x%x expected 0x%x/0x%x",
350*27b03b36SApple OSS Distributions 	    *cp1, *cp2, '1', '1');
351*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
352*27b03b36SApple OSS Distributions 		goto done;
353*27b03b36SApple OSS Distributions 	}
354*27b03b36SApple OSS Distributions 
355*27b03b36SApple OSS Distributions 	*cp2 = '2';
356*27b03b36SApple OSS Distributions 	T_QUIET;
357*27b03b36SApple OSS Distributions 	T_EXPECT_TRUE(((*cp1 == '1') && (*cp2 == '2')), "*cp1/*cp2 0x%x/0x%x expected 0x%x/0x%x",
358*27b03b36SApple OSS Distributions 	    *cp1, *cp2, '1', '2');
359*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
360*27b03b36SApple OSS Distributions 		goto done;
361*27b03b36SApple OSS Distributions 	}
362*27b03b36SApple OSS Distributions 
363*27b03b36SApple OSS Distributions done:
364*27b03b36SApple OSS Distributions 	if (vmaddr1 != 0) {
365*27b03b36SApple OSS Distributions 		mach_vm_deallocate(mach_task_self(), vmaddr1, vmsize1);
366*27b03b36SApple OSS Distributions 		vmaddr1 = 0;
367*27b03b36SApple OSS Distributions 		vmsize1 = 0;
368*27b03b36SApple OSS Distributions 	}
369*27b03b36SApple OSS Distributions 	if (vmaddr2 != 0) {
370*27b03b36SApple OSS Distributions 		mach_vm_deallocate(mach_task_self(), vmaddr2, vmsize2);
371*27b03b36SApple OSS Distributions 		vmaddr2 = 0;
372*27b03b36SApple OSS Distributions 		vmsize2 = 0;
373*27b03b36SApple OSS Distributions 	}
374*27b03b36SApple OSS Distributions 	if (mem_entry != MACH_PORT_NULL) {
375*27b03b36SApple OSS Distributions 		mach_port_deallocate(mach_task_self(), mem_entry);
376*27b03b36SApple OSS Distributions 		mem_entry = MACH_PORT_NULL;
377*27b03b36SApple OSS Distributions 	}
378*27b03b36SApple OSS Distributions 
379*27b03b36SApple OSS Distributions 	return;
380*27b03b36SApple OSS Distributions }
381*27b03b36SApple OSS Distributions 
382*27b03b36SApple OSS Distributions T_DECL(memory_entry_tagging, "test mem entry tag for rdar://problem/23334087 \
383*27b03b36SApple OSS Distributions     VM memory tags should be propagated through memory entries",
384*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
385*27b03b36SApple OSS Distributions {
386*27b03b36SApple OSS Distributions 	test_memory_entry_tagging(0);
387*27b03b36SApple OSS Distributions 	test_memory_entry_tagging(1);
388*27b03b36SApple OSS Distributions }
389*27b03b36SApple OSS Distributions 
390*27b03b36SApple OSS Distributions T_DECL(map_memory_entry, "test mapping mem entry for rdar://problem/22611816 \
391*27b03b36SApple OSS Distributions     mach_make_memory_entry(MAP_MEM_VM_COPY) should never use a KERNEL_BUFFER \
392*27b03b36SApple OSS Distributions     copy", T_META_ALL_VALID_ARCHS(true))
393*27b03b36SApple OSS Distributions {
394*27b03b36SApple OSS Distributions 	test_map_memory_entry();
395*27b03b36SApple OSS Distributions }
396*27b03b36SApple OSS Distributions 
397*27b03b36SApple OSS Distributions static char *vm_purgable_state[4] = { "NONVOLATILE", "VOLATILE", "EMPTY", "DENY" };
398*27b03b36SApple OSS Distributions 
399*27b03b36SApple OSS Distributions static uint64_t
task_footprint(void)400*27b03b36SApple OSS Distributions task_footprint(void)
401*27b03b36SApple OSS Distributions {
402*27b03b36SApple OSS Distributions 	task_vm_info_data_t ti;
403*27b03b36SApple OSS Distributions 	kern_return_t kr;
404*27b03b36SApple OSS Distributions 	mach_msg_type_number_t count;
405*27b03b36SApple OSS Distributions 
406*27b03b36SApple OSS Distributions 	count = TASK_VM_INFO_COUNT;
407*27b03b36SApple OSS Distributions 	kr = task_info(mach_task_self(),
408*27b03b36SApple OSS Distributions 	    TASK_VM_INFO,
409*27b03b36SApple OSS Distributions 	    (task_info_t) &ti,
410*27b03b36SApple OSS Distributions 	    &count);
411*27b03b36SApple OSS Distributions 	T_QUIET;
412*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "task_info()");
413*27b03b36SApple OSS Distributions #if defined(__arm64__) || defined(__arm__)
414*27b03b36SApple OSS Distributions 	T_QUIET;
415*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(count, TASK_VM_INFO_COUNT, "task_info() count = %d (expected %d)",
416*27b03b36SApple OSS Distributions 	    count, TASK_VM_INFO_COUNT);
417*27b03b36SApple OSS Distributions #endif /* defined(__arm64__) || defined(__arm__) */
418*27b03b36SApple OSS Distributions 	return ti.phys_footprint;
419*27b03b36SApple OSS Distributions }
420*27b03b36SApple OSS Distributions 
421*27b03b36SApple OSS Distributions T_DECL(purgeable_empty_to_volatile, "test task physical footprint when \
422*27b03b36SApple OSS Distributions     emptying, volatilizing purgeable vm")
423*27b03b36SApple OSS Distributions {
424*27b03b36SApple OSS Distributions 	kern_return_t kr;
425*27b03b36SApple OSS Distributions 	mach_vm_address_t vm_addr;
426*27b03b36SApple OSS Distributions 	mach_vm_size_t vm_size;
427*27b03b36SApple OSS Distributions 	char *cp;
428*27b03b36SApple OSS Distributions 	int ret;
429*27b03b36SApple OSS Distributions 	vm_purgable_t state;
430*27b03b36SApple OSS Distributions 	uint64_t footprint[8];
431*27b03b36SApple OSS Distributions 
432*27b03b36SApple OSS Distributions 	vm_addr = 0;
433*27b03b36SApple OSS Distributions 	vm_size = 1 * 1024 * 1024;
434*27b03b36SApple OSS Distributions 	T_LOG("--> allocate %llu bytes", vm_size);
435*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
436*27b03b36SApple OSS Distributions 	    &vm_addr,
437*27b03b36SApple OSS Distributions 	    vm_size,
438*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
439*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_allocate()");
440*27b03b36SApple OSS Distributions 
441*27b03b36SApple OSS Distributions 	/* footprint0 */
442*27b03b36SApple OSS Distributions 	footprint[0] = task_footprint();
443*27b03b36SApple OSS Distributions 	T_LOG("    footprint[0] = %llu", footprint[0]);
444*27b03b36SApple OSS Distributions 
445*27b03b36SApple OSS Distributions 	T_LOG("--> access %llu bytes", vm_size);
446*27b03b36SApple OSS Distributions 	for (cp = (char *) vm_addr;
447*27b03b36SApple OSS Distributions 	    cp < (char *) (vm_addr + vm_size);
448*27b03b36SApple OSS Distributions 	    cp += vm_kernel_page_size) {
449*27b03b36SApple OSS Distributions 		*cp = 'x';
450*27b03b36SApple OSS Distributions 	}
451*27b03b36SApple OSS Distributions 	/* footprint1 == footprint0 + vm_size */
452*27b03b36SApple OSS Distributions 	footprint[1] = task_footprint();
453*27b03b36SApple OSS Distributions 	T_LOG("    footprint[1] = %llu", footprint[1]);
454*27b03b36SApple OSS Distributions 	if (footprint[1] != footprint[0] + vm_size) {
455*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[1] != footprint[0] + vm_size");
456*27b03b36SApple OSS Distributions 	}
457*27b03b36SApple OSS Distributions 
458*27b03b36SApple OSS Distributions 	T_LOG("--> wire %llu bytes", vm_size / 2);
459*27b03b36SApple OSS Distributions 	ret = mlock((char *)vm_addr, (size_t) (vm_size / 2));
460*27b03b36SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "mlock()");
461*27b03b36SApple OSS Distributions 
462*27b03b36SApple OSS Distributions 	/* footprint2 == footprint1 */
463*27b03b36SApple OSS Distributions 	footprint[2] = task_footprint();
464*27b03b36SApple OSS Distributions 	T_LOG("    footprint[2] = %llu", footprint[2]);
465*27b03b36SApple OSS Distributions 	if (footprint[2] != footprint[1]) {
466*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[2] != footprint[1]");
467*27b03b36SApple OSS Distributions 	}
468*27b03b36SApple OSS Distributions 
469*27b03b36SApple OSS Distributions 	T_LOG("--> VOLATILE");
470*27b03b36SApple OSS Distributions 	state = VM_PURGABLE_VOLATILE;
471*27b03b36SApple OSS Distributions 	kr = mach_vm_purgable_control(mach_task_self(),
472*27b03b36SApple OSS Distributions 	    vm_addr,
473*27b03b36SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
474*27b03b36SApple OSS Distributions 	    &state);
475*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_purgable_control(VOLATILE)");
476*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE, "NONVOLATILE->VOLATILE: state was %s",
477*27b03b36SApple OSS Distributions 	    vm_purgable_state[state]);
478*27b03b36SApple OSS Distributions 	/* footprint3 == footprint2 - (vm_size / 2) */
479*27b03b36SApple OSS Distributions 	footprint[3] = task_footprint();
480*27b03b36SApple OSS Distributions 	T_LOG("    footprint[3] = %llu", footprint[3]);
481*27b03b36SApple OSS Distributions 	if (footprint[3] != footprint[2] - (vm_size / 2)) {
482*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[3] != footprint[2] - (vm_size / 2)");
483*27b03b36SApple OSS Distributions 	}
484*27b03b36SApple OSS Distributions 
485*27b03b36SApple OSS Distributions 	T_LOG("--> EMPTY");
486*27b03b36SApple OSS Distributions 	state = VM_PURGABLE_EMPTY;
487*27b03b36SApple OSS Distributions 	kr = mach_vm_purgable_control(mach_task_self(),
488*27b03b36SApple OSS Distributions 	    vm_addr,
489*27b03b36SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
490*27b03b36SApple OSS Distributions 	    &state);
491*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_purgable_control(EMPTY)");
492*27b03b36SApple OSS Distributions 	if (state != VM_PURGABLE_VOLATILE &&
493*27b03b36SApple OSS Distributions 	    state != VM_PURGABLE_EMPTY) {
494*27b03b36SApple OSS Distributions 		T_ASSERT_FAIL("VOLATILE->EMPTY: state was %s",
495*27b03b36SApple OSS Distributions 		    vm_purgable_state[state]);
496*27b03b36SApple OSS Distributions 	}
497*27b03b36SApple OSS Distributions 	/* footprint4 == footprint3 */
498*27b03b36SApple OSS Distributions 	footprint[4] = task_footprint();
499*27b03b36SApple OSS Distributions 	T_LOG("    footprint[4] = %llu", footprint[4]);
500*27b03b36SApple OSS Distributions 	if (footprint[4] != footprint[3]) {
501*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[4] != footprint[3]");
502*27b03b36SApple OSS Distributions 	}
503*27b03b36SApple OSS Distributions 
504*27b03b36SApple OSS Distributions 	T_LOG("--> unwire %llu bytes", vm_size / 2);
505*27b03b36SApple OSS Distributions 	ret = munlock((char *)vm_addr, (size_t) (vm_size / 2));
506*27b03b36SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "munlock()");
507*27b03b36SApple OSS Distributions 
508*27b03b36SApple OSS Distributions 	/* footprint5 == footprint4 - (vm_size/2) (unless memory pressure) */
509*27b03b36SApple OSS Distributions 	/* footprint5 == footprint0 */
510*27b03b36SApple OSS Distributions 	footprint[5] = task_footprint();
511*27b03b36SApple OSS Distributions 	T_LOG("    footprint[5] = %llu", footprint[5]);
512*27b03b36SApple OSS Distributions 	if (footprint[5] != footprint[4] - (vm_size / 2)) {
513*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[5] != footprint[4] - (vm_size/2)");
514*27b03b36SApple OSS Distributions 	}
515*27b03b36SApple OSS Distributions 	if (footprint[5] != footprint[0]) {
516*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[5] != footprint[0]");
517*27b03b36SApple OSS Distributions 	}
518*27b03b36SApple OSS Distributions 
519*27b03b36SApple OSS Distributions 	T_LOG("--> VOLATILE");
520*27b03b36SApple OSS Distributions 	state = VM_PURGABLE_VOLATILE;
521*27b03b36SApple OSS Distributions 	kr = mach_vm_purgable_control(mach_task_self(),
522*27b03b36SApple OSS Distributions 	    vm_addr,
523*27b03b36SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
524*27b03b36SApple OSS Distributions 	    &state);
525*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_purgable_control(VOLATILE)");
526*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_EMPTY, "EMPTY->VOLATILE: state == %s",
527*27b03b36SApple OSS Distributions 	    vm_purgable_state[state]);
528*27b03b36SApple OSS Distributions 	/* footprint6 == footprint5 */
529*27b03b36SApple OSS Distributions 	/* footprint6 == footprint0 */
530*27b03b36SApple OSS Distributions 	footprint[6] = task_footprint();
531*27b03b36SApple OSS Distributions 	T_LOG("    footprint[6] = %llu", footprint[6]);
532*27b03b36SApple OSS Distributions 	if (footprint[6] != footprint[5]) {
533*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[6] != footprint[5]");
534*27b03b36SApple OSS Distributions 	}
535*27b03b36SApple OSS Distributions 	if (footprint[6] != footprint[0]) {
536*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[6] != footprint[0]");
537*27b03b36SApple OSS Distributions 	}
538*27b03b36SApple OSS Distributions 
539*27b03b36SApple OSS Distributions 	T_LOG("--> NONVOLATILE");
540*27b03b36SApple OSS Distributions 	state = VM_PURGABLE_NONVOLATILE;
541*27b03b36SApple OSS Distributions 	kr = mach_vm_purgable_control(mach_task_self(),
542*27b03b36SApple OSS Distributions 	    vm_addr,
543*27b03b36SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
544*27b03b36SApple OSS Distributions 	    &state);
545*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_purgable_control(NONVOLATILE)");
546*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_EMPTY, "EMPTY->NONVOLATILE: state == %s",
547*27b03b36SApple OSS Distributions 	    vm_purgable_state[state]);
548*27b03b36SApple OSS Distributions 	/* footprint7 == footprint6 */
549*27b03b36SApple OSS Distributions 	/* footprint7 == footprint0 */
550*27b03b36SApple OSS Distributions 	footprint[7] = task_footprint();
551*27b03b36SApple OSS Distributions 	T_LOG("    footprint[7] = %llu", footprint[7]);
552*27b03b36SApple OSS Distributions 	if (footprint[7] != footprint[6]) {
553*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[7] != footprint[6]");
554*27b03b36SApple OSS Distributions 	}
555*27b03b36SApple OSS Distributions 	if (footprint[7] != footprint[0]) {
556*27b03b36SApple OSS Distributions 		T_LOG("WARN: footprint[7] != footprint[0]");
557*27b03b36SApple OSS Distributions 	}
558*27b03b36SApple OSS Distributions }
559*27b03b36SApple OSS Distributions 
560*27b03b36SApple OSS Distributions T_DECL(madvise_shared, "test madvise shared for rdar://problem/2295713 logging \
561*27b03b36SApple OSS Distributions     rethink needs madvise(MADV_FREE_HARDER)",
562*27b03b36SApple OSS Distributions     T_META_RUN_CONCURRENTLY(false),
563*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
564*27b03b36SApple OSS Distributions {
565*27b03b36SApple OSS Distributions 	vm_address_t            vmaddr = 0, vmaddr2 = 0;
566*27b03b36SApple OSS Distributions 	vm_size_t               vmsize;
567*27b03b36SApple OSS Distributions 	kern_return_t           kr;
568*27b03b36SApple OSS Distributions 	char                    *cp;
569*27b03b36SApple OSS Distributions 	vm_prot_t               curprot, maxprot;
570*27b03b36SApple OSS Distributions 	int                     ret;
571*27b03b36SApple OSS Distributions 	task_vm_info_data_t     ti;
572*27b03b36SApple OSS Distributions 	mach_msg_type_number_t  ti_count;
573*27b03b36SApple OSS Distributions 
574*27b03b36SApple OSS Distributions 	vmsize = 10 * 1024 * 1024; /* 10MB */
575*27b03b36SApple OSS Distributions 	kr = vm_allocate(mach_task_self(),
576*27b03b36SApple OSS Distributions 	    &vmaddr,
577*27b03b36SApple OSS Distributions 	    vmsize,
578*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
579*27b03b36SApple OSS Distributions 	T_QUIET;
580*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "vm_allocate()");
581*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
582*27b03b36SApple OSS Distributions 		goto done;
583*27b03b36SApple OSS Distributions 	}
584*27b03b36SApple OSS Distributions 
585*27b03b36SApple OSS Distributions 	for (cp = (char *)(uintptr_t)vmaddr;
586*27b03b36SApple OSS Distributions 	    cp < (char *)(uintptr_t)(vmaddr + vmsize);
587*27b03b36SApple OSS Distributions 	    cp++) {
588*27b03b36SApple OSS Distributions 		*cp = 'x';
589*27b03b36SApple OSS Distributions 	}
590*27b03b36SApple OSS Distributions 
591*27b03b36SApple OSS Distributions 	kr = vm_remap(mach_task_self(),
592*27b03b36SApple OSS Distributions 	    &vmaddr2,
593*27b03b36SApple OSS Distributions 	    vmsize,
594*27b03b36SApple OSS Distributions 	    0,           /* mask */
595*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
596*27b03b36SApple OSS Distributions 	    mach_task_self(),
597*27b03b36SApple OSS Distributions 	    vmaddr,
598*27b03b36SApple OSS Distributions 	    FALSE,           /* copy */
599*27b03b36SApple OSS Distributions 	    &curprot,
600*27b03b36SApple OSS Distributions 	    &maxprot,
601*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
602*27b03b36SApple OSS Distributions 	T_QUIET;
603*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "vm_remap()");
604*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
605*27b03b36SApple OSS Distributions 		goto done;
606*27b03b36SApple OSS Distributions 	}
607*27b03b36SApple OSS Distributions 
608*27b03b36SApple OSS Distributions 	for (cp = (char *)(uintptr_t)vmaddr2;
609*27b03b36SApple OSS Distributions 	    cp < (char *)(uintptr_t)(vmaddr2 + vmsize);
610*27b03b36SApple OSS Distributions 	    cp++) {
611*27b03b36SApple OSS Distributions 		T_QUIET;
612*27b03b36SApple OSS Distributions 		T_EXPECT_EQ(*cp, 'x', "vmaddr=%p vmaddr2=%p %p:0x%x",
613*27b03b36SApple OSS Distributions 		    (void *)(uintptr_t)vmaddr,
614*27b03b36SApple OSS Distributions 		    (void *)(uintptr_t)vmaddr2,
615*27b03b36SApple OSS Distributions 		    (void *)cp,
616*27b03b36SApple OSS Distributions 		    (unsigned char)*cp);
617*27b03b36SApple OSS Distributions 		if (T_RESULT == T_RESULT_FAIL) {
618*27b03b36SApple OSS Distributions 			goto done;
619*27b03b36SApple OSS Distributions 		}
620*27b03b36SApple OSS Distributions 	}
621*27b03b36SApple OSS Distributions 	cp = (char *)(uintptr_t)vmaddr;
622*27b03b36SApple OSS Distributions 	*cp = 'X';
623*27b03b36SApple OSS Distributions 	cp = (char *)(uintptr_t)vmaddr2;
624*27b03b36SApple OSS Distributions 	T_QUIET;
625*27b03b36SApple OSS Distributions 	T_EXPECT_EQ(*cp, 'X', "memory was not properly shared");
626*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
627*27b03b36SApple OSS Distributions 		goto done;
628*27b03b36SApple OSS Distributions 	}
629*27b03b36SApple OSS Distributions 
630*27b03b36SApple OSS Distributions #if defined(__x86_64__) || defined(__i386__)
631*27b03b36SApple OSS Distributions 	if (COMM_PAGE_READ(uint64_t, CPU_CAPABILITIES64) & kIsTranslated) {
632*27b03b36SApple OSS Distributions 		T_LOG("Skipping madvise reusable tests because we're running under translation.");
633*27b03b36SApple OSS Distributions 		goto done;
634*27b03b36SApple OSS Distributions 	}
635*27b03b36SApple OSS Distributions #endif /* defined(__x86_64__) || defined(__i386__) */
636*27b03b36SApple OSS Distributions 	ret = madvise((char *)(uintptr_t)vmaddr,
637*27b03b36SApple OSS Distributions 	    vmsize,
638*27b03b36SApple OSS Distributions 	    MADV_FREE_REUSABLE);
639*27b03b36SApple OSS Distributions 	T_QUIET;
640*27b03b36SApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(ret, "madvise()");
641*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
642*27b03b36SApple OSS Distributions 		goto done;
643*27b03b36SApple OSS Distributions 	}
644*27b03b36SApple OSS Distributions 
645*27b03b36SApple OSS Distributions 	ti_count = TASK_VM_INFO_COUNT;
646*27b03b36SApple OSS Distributions 	kr = task_info(mach_task_self(),
647*27b03b36SApple OSS Distributions 	    TASK_VM_INFO,
648*27b03b36SApple OSS Distributions 	    (task_info_t) &ti,
649*27b03b36SApple OSS Distributions 	    &ti_count);
650*27b03b36SApple OSS Distributions 	T_QUIET;
651*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "task_info()");
652*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
653*27b03b36SApple OSS Distributions 		goto done;
654*27b03b36SApple OSS Distributions 	}
655*27b03b36SApple OSS Distributions 
656*27b03b36SApple OSS Distributions 	T_QUIET;
657*27b03b36SApple OSS Distributions 	T_EXPECT_EQ(ti.reusable, 2ULL * vmsize, "ti.reusable=%lld expected %lld",
658*27b03b36SApple OSS Distributions 	    ti.reusable, (uint64_t)(2 * vmsize));
659*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
660*27b03b36SApple OSS Distributions 		goto done;
661*27b03b36SApple OSS Distributions 	}
662*27b03b36SApple OSS Distributions 
663*27b03b36SApple OSS Distributions done:
664*27b03b36SApple OSS Distributions 	if (vmaddr != 0) {
665*27b03b36SApple OSS Distributions 		vm_deallocate(mach_task_self(), vmaddr, vmsize);
666*27b03b36SApple OSS Distributions 		vmaddr = 0;
667*27b03b36SApple OSS Distributions 	}
668*27b03b36SApple OSS Distributions 	if (vmaddr2 != 0) {
669*27b03b36SApple OSS Distributions 		vm_deallocate(mach_task_self(), vmaddr2, vmsize);
670*27b03b36SApple OSS Distributions 		vmaddr2 = 0;
671*27b03b36SApple OSS Distributions 	}
672*27b03b36SApple OSS Distributions }
673*27b03b36SApple OSS Distributions 
674*27b03b36SApple OSS Distributions T_DECL(madvise_purgeable_can_reuse, "test madvise purgeable can reuse for \
675*27b03b36SApple OSS Distributions     rdar://problem/37476183 Preview Footprint memory regressions ~100MB \
676*27b03b36SApple OSS Distributions     [ purgeable_malloc became eligible for reuse ]",
677*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
678*27b03b36SApple OSS Distributions {
679*27b03b36SApple OSS Distributions #if defined(__x86_64__) || defined(__i386__)
680*27b03b36SApple OSS Distributions 	if (COMM_PAGE_READ(uint64_t, CPU_CAPABILITIES64) & kIsTranslated) {
681*27b03b36SApple OSS Distributions 		T_SKIP("madvise reusable is not supported under Rosetta translation. Skipping.)");
682*27b03b36SApple OSS Distributions 	}
683*27b03b36SApple OSS Distributions #endif /* defined(__x86_64__) || defined(__i386__) */
684*27b03b36SApple OSS Distributions 	vm_address_t            vmaddr = 0;
685*27b03b36SApple OSS Distributions 	vm_size_t               vmsize;
686*27b03b36SApple OSS Distributions 	kern_return_t           kr;
687*27b03b36SApple OSS Distributions 	char                    *cp;
688*27b03b36SApple OSS Distributions 	int                     ret;
689*27b03b36SApple OSS Distributions 
690*27b03b36SApple OSS Distributions 	vmsize = 10 * 1024 * 1024; /* 10MB */
691*27b03b36SApple OSS Distributions 	kr = vm_allocate(mach_task_self(),
692*27b03b36SApple OSS Distributions 	    &vmaddr,
693*27b03b36SApple OSS Distributions 	    vmsize,
694*27b03b36SApple OSS Distributions 	    (VM_FLAGS_ANYWHERE |
695*27b03b36SApple OSS Distributions 	    VM_FLAGS_PURGABLE |
696*27b03b36SApple OSS Distributions 	    VM_MAKE_TAG(VM_MEMORY_MALLOC)));
697*27b03b36SApple OSS Distributions 	T_QUIET;
698*27b03b36SApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "vm_allocate()");
699*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
700*27b03b36SApple OSS Distributions 		goto done;
701*27b03b36SApple OSS Distributions 	}
702*27b03b36SApple OSS Distributions 
703*27b03b36SApple OSS Distributions 	for (cp = (char *)(uintptr_t)vmaddr;
704*27b03b36SApple OSS Distributions 	    cp < (char *)(uintptr_t)(vmaddr + vmsize);
705*27b03b36SApple OSS Distributions 	    cp++) {
706*27b03b36SApple OSS Distributions 		*cp = 'x';
707*27b03b36SApple OSS Distributions 	}
708*27b03b36SApple OSS Distributions 
709*27b03b36SApple OSS Distributions 	ret = madvise((char *)(uintptr_t)vmaddr,
710*27b03b36SApple OSS Distributions 	    vmsize,
711*27b03b36SApple OSS Distributions 	    MADV_CAN_REUSE);
712*27b03b36SApple OSS Distributions 	T_QUIET;
713*27b03b36SApple OSS Distributions 	T_EXPECT_TRUE(((ret == -1) && (errno == EINVAL)), "madvise(): purgeable vm can't be adviced to reuse");
714*27b03b36SApple OSS Distributions 	if (T_RESULT == T_RESULT_FAIL) {
715*27b03b36SApple OSS Distributions 		goto done;
716*27b03b36SApple OSS Distributions 	}
717*27b03b36SApple OSS Distributions 
718*27b03b36SApple OSS Distributions done:
719*27b03b36SApple OSS Distributions 	if (vmaddr != 0) {
720*27b03b36SApple OSS Distributions 		vm_deallocate(mach_task_self(), vmaddr, vmsize);
721*27b03b36SApple OSS Distributions 		vmaddr = 0;
722*27b03b36SApple OSS Distributions 	}
723*27b03b36SApple OSS Distributions }
724*27b03b36SApple OSS Distributions 
725*27b03b36SApple OSS Distributions #define DEST_PATTERN 0xFEDCBA98
726*27b03b36SApple OSS Distributions 
727*27b03b36SApple OSS Distributions T_DECL(map_read_overwrite, "test overwriting vm map from other map - \
728*27b03b36SApple OSS Distributions     rdar://31075370",
729*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
730*27b03b36SApple OSS Distributions {
731*27b03b36SApple OSS Distributions 	kern_return_t           kr;
732*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr1, vmaddr2;
733*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize1, vmsize2;
734*27b03b36SApple OSS Distributions 	int                     *ip;
735*27b03b36SApple OSS Distributions 	int                     i;
736*27b03b36SApple OSS Distributions 
737*27b03b36SApple OSS Distributions 	vmaddr1 = 0;
738*27b03b36SApple OSS Distributions 	vmsize1 = 4 * 4096;
739*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
740*27b03b36SApple OSS Distributions 	    &vmaddr1,
741*27b03b36SApple OSS Distributions 	    vmsize1,
742*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
743*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_allocate()");
744*27b03b36SApple OSS Distributions 
745*27b03b36SApple OSS Distributions 	ip = (int *)(uintptr_t)vmaddr1;
746*27b03b36SApple OSS Distributions 	for (i = 0; i < vmsize1 / sizeof(*ip); i++) {
747*27b03b36SApple OSS Distributions 		ip[i] = i;
748*27b03b36SApple OSS Distributions 	}
749*27b03b36SApple OSS Distributions 
750*27b03b36SApple OSS Distributions 	vmaddr2 = 0;
751*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
752*27b03b36SApple OSS Distributions 	    &vmaddr2,
753*27b03b36SApple OSS Distributions 	    vmsize1,
754*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
755*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_allocate()");
756*27b03b36SApple OSS Distributions 
757*27b03b36SApple OSS Distributions 	ip = (int *)(uintptr_t)vmaddr2;
758*27b03b36SApple OSS Distributions 	for (i = 0; i < vmsize1 / sizeof(*ip); i++) {
759*27b03b36SApple OSS Distributions 		ip[i] = DEST_PATTERN;
760*27b03b36SApple OSS Distributions 	}
761*27b03b36SApple OSS Distributions 
762*27b03b36SApple OSS Distributions 	vmsize2 = vmsize1 - 2 * (sizeof(*ip));
763*27b03b36SApple OSS Distributions 	kr = mach_vm_read_overwrite(mach_task_self(),
764*27b03b36SApple OSS Distributions 	    vmaddr1 + sizeof(*ip),
765*27b03b36SApple OSS Distributions 	    vmsize2,
766*27b03b36SApple OSS Distributions 	    vmaddr2 + sizeof(*ip),
767*27b03b36SApple OSS Distributions 	    &vmsize2);
768*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_read_overwrite()");
769*27b03b36SApple OSS Distributions 
770*27b03b36SApple OSS Distributions 	ip = (int *)(uintptr_t)vmaddr2;
771*27b03b36SApple OSS Distributions 	for (i = 0; i < 1; i++) {
772*27b03b36SApple OSS Distributions 		T_QUIET;
773*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(ip[i], DEST_PATTERN, "vmaddr2[%d] = 0x%x instead of 0x%x",
774*27b03b36SApple OSS Distributions 		    i, ip[i], DEST_PATTERN);
775*27b03b36SApple OSS Distributions 	}
776*27b03b36SApple OSS Distributions 	for (; i < (vmsize1 - 2) / sizeof(*ip); i++) {
777*27b03b36SApple OSS Distributions 		T_QUIET;
778*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(ip[i], i, "vmaddr2[%d] = 0x%x instead of 0x%x",
779*27b03b36SApple OSS Distributions 		    i, ip[i], i);
780*27b03b36SApple OSS Distributions 	}
781*27b03b36SApple OSS Distributions 	for (; i < vmsize1 / sizeof(*ip); i++) {
782*27b03b36SApple OSS Distributions 		T_QUIET;
783*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(ip[i], DEST_PATTERN, "vmaddr2[%d] = 0x%x instead of 0x%x",
784*27b03b36SApple OSS Distributions 		    i, ip[i], DEST_PATTERN);
785*27b03b36SApple OSS Distributions 	}
786*27b03b36SApple OSS Distributions }
787*27b03b36SApple OSS Distributions 
788*27b03b36SApple OSS Distributions T_DECL(copy_none_use_pmap, "test copy-on-write remapping of COPY_NONE vm \
789*27b03b36SApple OSS Distributions     objects - rdar://35610377",
790*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
791*27b03b36SApple OSS Distributions {
792*27b03b36SApple OSS Distributions 	kern_return_t           kr;
793*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr1, vmaddr2, vmaddr3;
794*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize;
795*27b03b36SApple OSS Distributions 	vm_prot_t               curprot, maxprot;
796*27b03b36SApple OSS Distributions 
797*27b03b36SApple OSS Distributions 	vmsize = 32 * 1024 * 1024;
798*27b03b36SApple OSS Distributions 
799*27b03b36SApple OSS Distributions 	vmaddr1 = 0;
800*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
801*27b03b36SApple OSS Distributions 	    &vmaddr1,
802*27b03b36SApple OSS Distributions 	    vmsize,
803*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
804*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_allocate()");
805*27b03b36SApple OSS Distributions 
806*27b03b36SApple OSS Distributions 	memset((void *)(uintptr_t)vmaddr1, 'x', vmsize);
807*27b03b36SApple OSS Distributions 
808*27b03b36SApple OSS Distributions 	vmaddr2 = 0;
809*27b03b36SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
810*27b03b36SApple OSS Distributions 	    &vmaddr2,
811*27b03b36SApple OSS Distributions 	    vmsize,
812*27b03b36SApple OSS Distributions 	    0,                /* mask */
813*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
814*27b03b36SApple OSS Distributions 	    mach_task_self(),
815*27b03b36SApple OSS Distributions 	    vmaddr1,
816*27b03b36SApple OSS Distributions 	    TRUE,                /* copy */
817*27b03b36SApple OSS Distributions 	    &curprot,
818*27b03b36SApple OSS Distributions 	    &maxprot,
819*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
820*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_remap() #1");
821*27b03b36SApple OSS Distributions 
822*27b03b36SApple OSS Distributions 	vmaddr3 = 0;
823*27b03b36SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
824*27b03b36SApple OSS Distributions 	    &vmaddr3,
825*27b03b36SApple OSS Distributions 	    vmsize,
826*27b03b36SApple OSS Distributions 	    0,                /* mask */
827*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
828*27b03b36SApple OSS Distributions 	    mach_task_self(),
829*27b03b36SApple OSS Distributions 	    vmaddr2,
830*27b03b36SApple OSS Distributions 	    TRUE,                /* copy */
831*27b03b36SApple OSS Distributions 	    &curprot,
832*27b03b36SApple OSS Distributions 	    &maxprot,
833*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
834*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_remap() #2");
835*27b03b36SApple OSS Distributions }
836*27b03b36SApple OSS Distributions 
837*27b03b36SApple OSS Distributions T_DECL(purgable_deny, "test purgeable memory is not allowed to be converted to \
838*27b03b36SApple OSS Distributions     non-purgeable - rdar://31990033",
839*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
840*27b03b36SApple OSS Distributions {
841*27b03b36SApple OSS Distributions 	kern_return_t   kr;
842*27b03b36SApple OSS Distributions 	vm_address_t    vmaddr;
843*27b03b36SApple OSS Distributions 	vm_purgable_t   state;
844*27b03b36SApple OSS Distributions 
845*27b03b36SApple OSS Distributions 	vmaddr = 0;
846*27b03b36SApple OSS Distributions 	kr = vm_allocate(mach_task_self(), &vmaddr, 1,
847*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
848*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_allocate()");
849*27b03b36SApple OSS Distributions 
850*27b03b36SApple OSS Distributions 	state = VM_PURGABLE_DENY;
851*27b03b36SApple OSS Distributions 	kr = vm_purgable_control(mach_task_self(), vmaddr,
852*27b03b36SApple OSS Distributions 	    VM_PURGABLE_SET_STATE, &state);
853*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(kr, KERN_INVALID_ARGUMENT,
854*27b03b36SApple OSS Distributions 	    "vm_purgable_control(VM_PURGABLE_DENY) -> 0x%x (%s)",
855*27b03b36SApple OSS Distributions 	    kr, mach_error_string(kr));
856*27b03b36SApple OSS Distributions 
857*27b03b36SApple OSS Distributions 	kr = vm_deallocate(mach_task_self(), vmaddr, 1);
858*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate()");
859*27b03b36SApple OSS Distributions }
860*27b03b36SApple OSS Distributions 
861*27b03b36SApple OSS Distributions #define VMSIZE 0x10000
862*27b03b36SApple OSS Distributions 
863*27b03b36SApple OSS Distributions T_DECL(vm_remap_zero, "test vm map of zero size - rdar://33114981",
864*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
865*27b03b36SApple OSS Distributions {
866*27b03b36SApple OSS Distributions 	kern_return_t           kr;
867*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr1, vmaddr2;
868*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize;
869*27b03b36SApple OSS Distributions 	vm_prot_t               curprot, maxprot;
870*27b03b36SApple OSS Distributions 
871*27b03b36SApple OSS Distributions 	vmaddr1 = 0;
872*27b03b36SApple OSS Distributions 	vmsize = VMSIZE;
873*27b03b36SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
874*27b03b36SApple OSS Distributions 	    &vmaddr1,
875*27b03b36SApple OSS Distributions 	    vmsize,
876*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
877*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_allocate()");
878*27b03b36SApple OSS Distributions 
879*27b03b36SApple OSS Distributions 	vmaddr2 = 0;
880*27b03b36SApple OSS Distributions 	vmsize = 0;
881*27b03b36SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
882*27b03b36SApple OSS Distributions 	    &vmaddr2,
883*27b03b36SApple OSS Distributions 	    vmsize,
884*27b03b36SApple OSS Distributions 	    0,
885*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
886*27b03b36SApple OSS Distributions 	    mach_task_self(),
887*27b03b36SApple OSS Distributions 	    vmaddr1,
888*27b03b36SApple OSS Distributions 	    FALSE,
889*27b03b36SApple OSS Distributions 	    &curprot,
890*27b03b36SApple OSS Distributions 	    &maxprot,
891*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
892*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(kr, KERN_INVALID_ARGUMENT, "vm_remap(size=0x%llx) 0x%x (%s)",
893*27b03b36SApple OSS Distributions 	    vmsize, kr, mach_error_string(kr));
894*27b03b36SApple OSS Distributions 
895*27b03b36SApple OSS Distributions 	vmaddr2 = 0;
896*27b03b36SApple OSS Distributions 	vmsize = (mach_vm_size_t)-2;
897*27b03b36SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
898*27b03b36SApple OSS Distributions 	    &vmaddr2,
899*27b03b36SApple OSS Distributions 	    vmsize,
900*27b03b36SApple OSS Distributions 	    0,
901*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
902*27b03b36SApple OSS Distributions 	    mach_task_self(),
903*27b03b36SApple OSS Distributions 	    vmaddr1,
904*27b03b36SApple OSS Distributions 	    FALSE,
905*27b03b36SApple OSS Distributions 	    &curprot,
906*27b03b36SApple OSS Distributions 	    &maxprot,
907*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
908*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(kr, KERN_INVALID_ARGUMENT, "vm_remap(size=0x%llx) 0x%x (%s)",
909*27b03b36SApple OSS Distributions 	    vmsize, kr, mach_error_string(kr));
910*27b03b36SApple OSS Distributions }
911*27b03b36SApple OSS Distributions 
912*27b03b36SApple OSS Distributions extern int __shared_region_check_np(uint64_t *);
913*27b03b36SApple OSS Distributions 
914*27b03b36SApple OSS Distributions T_DECL(nested_pmap_trigger, "nested pmap should only be triggered from kernel \
915*27b03b36SApple OSS Distributions     - rdar://problem/41481703",
916*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
917*27b03b36SApple OSS Distributions {
918*27b03b36SApple OSS Distributions 	int                     ret;
919*27b03b36SApple OSS Distributions 	kern_return_t           kr;
920*27b03b36SApple OSS Distributions 	mach_vm_address_t       sr_start;
921*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize;
922*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr;
923*27b03b36SApple OSS Distributions 	mach_port_t             mem_entry;
924*27b03b36SApple OSS Distributions 
925*27b03b36SApple OSS Distributions 	ret = __shared_region_check_np(&sr_start);
926*27b03b36SApple OSS Distributions 	if (ret != 0) {
927*27b03b36SApple OSS Distributions 		int saved_errno;
928*27b03b36SApple OSS Distributions 		saved_errno = errno;
929*27b03b36SApple OSS Distributions 
930*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(saved_errno, ENOMEM, "__shared_region_check_np() %d (%s)",
931*27b03b36SApple OSS Distributions 		    saved_errno, strerror(saved_errno));
932*27b03b36SApple OSS Distributions 		T_END;
933*27b03b36SApple OSS Distributions 	}
934*27b03b36SApple OSS Distributions 
935*27b03b36SApple OSS Distributions 	vmsize = PAGE_SIZE;
936*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
937*27b03b36SApple OSS Distributions 	    &vmsize,
938*27b03b36SApple OSS Distributions 	    sr_start,
939*27b03b36SApple OSS Distributions 	    MAP_MEM_VM_SHARE | VM_PROT_READ,
940*27b03b36SApple OSS Distributions 	    &mem_entry,
941*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
942*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "make_memory_entry(0x%llx)", sr_start);
943*27b03b36SApple OSS Distributions 
944*27b03b36SApple OSS Distributions 	vmaddr = 0;
945*27b03b36SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(),
946*27b03b36SApple OSS Distributions 	    &vmaddr,
947*27b03b36SApple OSS Distributions 	    vmsize,
948*27b03b36SApple OSS Distributions 	    0,
949*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
950*27b03b36SApple OSS Distributions 	    mem_entry,
951*27b03b36SApple OSS Distributions 	    0,
952*27b03b36SApple OSS Distributions 	    FALSE,
953*27b03b36SApple OSS Distributions 	    VM_PROT_READ,
954*27b03b36SApple OSS Distributions 	    VM_PROT_READ,
955*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
956*27b03b36SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "vm_map()");
957*27b03b36SApple OSS Distributions }
958*27b03b36SApple OSS Distributions 
959*27b03b36SApple OSS Distributions static const char *prot_str[] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" };
960*27b03b36SApple OSS Distributions static const char *share_mode_str[] = { "---", "COW", "PRIVATE", "EMPTY", "SHARED", "TRUESHARED", "PRIVATE_ALIASED", "SHARED_ALIASED", "LARGE_PAGE" };
961*27b03b36SApple OSS Distributions 
962*27b03b36SApple OSS Distributions T_DECL(shared_region_share_writable, "sharing a writable mapping of the shared region shoudl not give write access to shared region - rdar://problem/74469953",
963*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
964*27b03b36SApple OSS Distributions {
965*27b03b36SApple OSS Distributions 	int ret;
966*27b03b36SApple OSS Distributions 	uint64_t sr_start;
967*27b03b36SApple OSS Distributions 	kern_return_t kr;
968*27b03b36SApple OSS Distributions 	mach_vm_address_t address, tmp_address, remap_address;
969*27b03b36SApple OSS Distributions 	mach_vm_size_t size, tmp_size, remap_size;
970*27b03b36SApple OSS Distributions 	uint32_t depth;
971*27b03b36SApple OSS Distributions 	mach_msg_type_number_t count;
972*27b03b36SApple OSS Distributions 	vm_region_submap_info_data_64_t info;
973*27b03b36SApple OSS Distributions 	vm_prot_t cur_prot, max_prot;
974*27b03b36SApple OSS Distributions 	uint32_t before, after, remap;
975*27b03b36SApple OSS Distributions 	mach_port_t mem_entry;
976*27b03b36SApple OSS Distributions 
977*27b03b36SApple OSS Distributions 	ret = __shared_region_check_np(&sr_start);
978*27b03b36SApple OSS Distributions 	if (ret != 0) {
979*27b03b36SApple OSS Distributions 		int saved_errno;
980*27b03b36SApple OSS Distributions 		saved_errno = errno;
981*27b03b36SApple OSS Distributions 
982*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(saved_errno, ENOMEM, "__shared_region_check_np() %d (%s)",
983*27b03b36SApple OSS Distributions 		    saved_errno, strerror(saved_errno));
984*27b03b36SApple OSS Distributions 		T_END;
985*27b03b36SApple OSS Distributions 	}
986*27b03b36SApple OSS Distributions 	T_LOG("SHARED_REGION_BASE 0x%llx", SHARED_REGION_BASE);
987*27b03b36SApple OSS Distributions 	T_LOG("SHARED_REGION_SIZE 0x%llx", SHARED_REGION_SIZE);
988*27b03b36SApple OSS Distributions 	T_LOG("shared region starts at 0x%llx", sr_start);
989*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GE(sr_start, SHARED_REGION_BASE,
990*27b03b36SApple OSS Distributions 	    "shared region starts below BASE");
991*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_LT(sr_start, SHARED_REGION_BASE + SHARED_REGION_SIZE,
992*27b03b36SApple OSS Distributions 	    "shared region starts above BASE+SIZE");
993*27b03b36SApple OSS Distributions 
994*27b03b36SApple OSS Distributions 	/*
995*27b03b36SApple OSS Distributions 	 * Step 1 - check that one can not get write access to a read-only
996*27b03b36SApple OSS Distributions 	 * mapping in the shared region.
997*27b03b36SApple OSS Distributions 	 */
998*27b03b36SApple OSS Distributions 	size = 0;
999*27b03b36SApple OSS Distributions 	for (address = SHARED_REGION_BASE;
1000*27b03b36SApple OSS Distributions 	    address < SHARED_REGION_BASE + SHARED_REGION_SIZE;
1001*27b03b36SApple OSS Distributions 	    address += size) {
1002*27b03b36SApple OSS Distributions 		size = 0;
1003*27b03b36SApple OSS Distributions 		depth = 99;
1004*27b03b36SApple OSS Distributions 		count = VM_REGION_SUBMAP_INFO_COUNT_64;
1005*27b03b36SApple OSS Distributions 		kr = mach_vm_region_recurse(mach_task_self(),
1006*27b03b36SApple OSS Distributions 		    &address,
1007*27b03b36SApple OSS Distributions 		    &size,
1008*27b03b36SApple OSS Distributions 		    &depth,
1009*27b03b36SApple OSS Distributions 		    (vm_region_recurse_info_t)&info,
1010*27b03b36SApple OSS Distributions 		    &count);
1011*27b03b36SApple OSS Distributions 		T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_region_recurse()");
1012*27b03b36SApple OSS Distributions 		if (kr == KERN_INVALID_ADDRESS) {
1013*27b03b36SApple OSS Distributions 			T_SKIP("could not find read-only nested mapping");
1014*27b03b36SApple OSS Distributions 			T_END;
1015*27b03b36SApple OSS Distributions 		}
1016*27b03b36SApple OSS Distributions 		T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1017*27b03b36SApple OSS Distributions 		T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1018*27b03b36SApple OSS Distributions 		    address, address + size, depth,
1019*27b03b36SApple OSS Distributions 		    prot_str[info.protection],
1020*27b03b36SApple OSS Distributions 		    prot_str[info.max_protection],
1021*27b03b36SApple OSS Distributions 		    share_mode_str[info.share_mode],
1022*27b03b36SApple OSS Distributions 		    info.object_id);
1023*27b03b36SApple OSS Distributions 		if (depth > 0 &&
1024*27b03b36SApple OSS Distributions 		    (info.protection == VM_PROT_READ) &&
1025*27b03b36SApple OSS Distributions 		    (info.max_protection == VM_PROT_READ)) {
1026*27b03b36SApple OSS Distributions 			/* nested and read-only: bingo! */
1027*27b03b36SApple OSS Distributions 			break;
1028*27b03b36SApple OSS Distributions 		}
1029*27b03b36SApple OSS Distributions 	}
1030*27b03b36SApple OSS Distributions 	if (address >= SHARED_REGION_BASE + SHARED_REGION_SIZE) {
1031*27b03b36SApple OSS Distributions 		T_SKIP("could not find read-only nested mapping");
1032*27b03b36SApple OSS Distributions 		T_END;
1033*27b03b36SApple OSS Distributions 	}
1034*27b03b36SApple OSS Distributions 
1035*27b03b36SApple OSS Distributions 	/* test vm_remap() of RO */
1036*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1037*27b03b36SApple OSS Distributions 	remap_address = 0;
1038*27b03b36SApple OSS Distributions 	remap_size = size;
1039*27b03b36SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
1040*27b03b36SApple OSS Distributions 	    &remap_address,
1041*27b03b36SApple OSS Distributions 	    remap_size,
1042*27b03b36SApple OSS Distributions 	    0,
1043*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR,
1044*27b03b36SApple OSS Distributions 	    mach_task_self(),
1045*27b03b36SApple OSS Distributions 	    address,
1046*27b03b36SApple OSS Distributions 	    FALSE,
1047*27b03b36SApple OSS Distributions 	    &cur_prot,
1048*27b03b36SApple OSS Distributions 	    &max_prot,
1049*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1050*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_remap()");
1051*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(cur_prot, VM_PROT_READ, "cur_prot is read-only");
1052*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(max_prot, VM_PROT_READ, "max_prot is read-only");
1053*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1054*27b03b36SApple OSS Distributions 	tmp_address = address;
1055*27b03b36SApple OSS Distributions 	tmp_size = 0;
1056*27b03b36SApple OSS Distributions 	depth = 99;
1057*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1058*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1059*27b03b36SApple OSS Distributions 	    &tmp_address,
1060*27b03b36SApple OSS Distributions 	    &tmp_size,
1061*27b03b36SApple OSS Distributions 	    &depth,
1062*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1063*27b03b36SApple OSS Distributions 	    &count);
1064*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1065*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1066*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1067*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1068*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1069*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1070*27b03b36SApple OSS Distributions 	    info.object_id);
1071*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1072*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1073*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1074*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_READ, "cur_prot still read-only");
1075*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(info.max_protection, VM_PROT_READ, "max_prot still read-only");
1076*27b03b36SApple OSS Distributions 	/* check that new mapping is read-only */
1077*27b03b36SApple OSS Distributions 	tmp_address = remap_address;
1078*27b03b36SApple OSS Distributions 	tmp_size = 0;
1079*27b03b36SApple OSS Distributions 	depth = 99;
1080*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1081*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1082*27b03b36SApple OSS Distributions 	    &tmp_address,
1083*27b03b36SApple OSS Distributions 	    &tmp_size,
1084*27b03b36SApple OSS Distributions 	    &depth,
1085*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1086*27b03b36SApple OSS Distributions 	    &count);
1087*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1088*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1089*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1090*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1091*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1092*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1093*27b03b36SApple OSS Distributions 	    info.object_id);
1094*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, remap_address, "address hasn't changed");
1095*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1096*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_READ, "new cur_prot read-only");
1097*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(info.max_protection, VM_PROT_READ, "new max_prot read-only");
1098*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1099*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1100*27b03b36SApple OSS Distributions // this would crash if actually read-only:
1101*27b03b36SApple OSS Distributions //	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1102*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1103*27b03b36SApple OSS Distributions 	T_LOG("vm_remap(): 0x%llx 0x%x -> 0x%x", address, before, after);
1104*27b03b36SApple OSS Distributions //	*(uint32_t *)(uintptr_t)remap_address = before;
1105*27b03b36SApple OSS Distributions 	if (before != after) {
1106*27b03b36SApple OSS Distributions 		T_FAIL("vm_remap() bypassed copy-on-write");
1107*27b03b36SApple OSS Distributions 	} else {
1108*27b03b36SApple OSS Distributions 		T_PASS("vm_remap() did not bypass copy-on-write");
1109*27b03b36SApple OSS Distributions 	}
1110*27b03b36SApple OSS Distributions 	/* cleanup */
1111*27b03b36SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), remap_address, remap_size);
1112*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_deallocate()");
1113*27b03b36SApple OSS Distributions 	T_PASS("vm_remap() read-only");
1114*27b03b36SApple OSS Distributions 
1115*27b03b36SApple OSS Distributions #if defined(VM_MEMORY_ROSETTA)
1116*27b03b36SApple OSS Distributions 	if (dlsym(RTLD_DEFAULT, "mach_vm_remap_new") == NULL) {
1117*27b03b36SApple OSS Distributions 		T_PASS("vm_remap_new() is not present");
1118*27b03b36SApple OSS Distributions 		goto skip_vm_remap_new_ro;
1119*27b03b36SApple OSS Distributions 	}
1120*27b03b36SApple OSS Distributions 	/* test vm_remap_new() of RO */
1121*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1122*27b03b36SApple OSS Distributions 	remap_address = 0;
1123*27b03b36SApple OSS Distributions 	remap_size = size;
1124*27b03b36SApple OSS Distributions 	cur_prot = VM_PROT_READ | VM_PROT_WRITE;
1125*27b03b36SApple OSS Distributions 	max_prot = VM_PROT_READ | VM_PROT_WRITE;
1126*27b03b36SApple OSS Distributions 	kr = mach_vm_remap_new(mach_task_self(),
1127*27b03b36SApple OSS Distributions 	    &remap_address,
1128*27b03b36SApple OSS Distributions 	    remap_size,
1129*27b03b36SApple OSS Distributions 	    0,
1130*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1131*27b03b36SApple OSS Distributions 	    mach_task_self(),
1132*27b03b36SApple OSS Distributions 	    address,
1133*27b03b36SApple OSS Distributions 	    FALSE,
1134*27b03b36SApple OSS Distributions 	    &cur_prot,
1135*27b03b36SApple OSS Distributions 	    &max_prot,
1136*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1137*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_remap_new()");
1138*27b03b36SApple OSS Distributions 	if (kr == KERN_PROTECTION_FAILURE) {
1139*27b03b36SApple OSS Distributions 		/* wrong but not a security issue... */
1140*27b03b36SApple OSS Distributions 		goto skip_vm_remap_new_ro;
1141*27b03b36SApple OSS Distributions 	}
1142*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_remap_new()");
1143*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1144*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1145*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1146*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1147*27b03b36SApple OSS Distributions 	T_LOG("vm_remap_new(): 0x%llx 0x%x -> 0x%x", address, before, after);
1148*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before;
1149*27b03b36SApple OSS Distributions 	if (before != after) {
1150*27b03b36SApple OSS Distributions 		T_FAIL("vm_remap_new() bypassed copy-on-write");
1151*27b03b36SApple OSS Distributions 	} else {
1152*27b03b36SApple OSS Distributions 		T_PASS("vm_remap_new() did not bypass copy-on-write");
1153*27b03b36SApple OSS Distributions 	}
1154*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1155*27b03b36SApple OSS Distributions 	tmp_address = address;
1156*27b03b36SApple OSS Distributions 	tmp_size = 0;
1157*27b03b36SApple OSS Distributions 	depth = 99;
1158*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1159*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1160*27b03b36SApple OSS Distributions 	    &tmp_address,
1161*27b03b36SApple OSS Distributions 	    &tmp_size,
1162*27b03b36SApple OSS Distributions 	    &depth,
1163*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1164*27b03b36SApple OSS Distributions 	    &count);
1165*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1166*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1167*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1168*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1169*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1170*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1171*27b03b36SApple OSS Distributions 	    info.object_id);
1172*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1173*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1174*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1175*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_READ, "cur_prot still read-only");
1176*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.max_protection, VM_PROT_READ, "max_prot still read-only");
1177*27b03b36SApple OSS Distributions 	T_PASS("vm_remap_new() read-only");
1178*27b03b36SApple OSS Distributions skip_vm_remap_new_ro:
1179*27b03b36SApple OSS Distributions #else /* defined(VM_MEMORY_ROSETTA) */
1180*27b03b36SApple OSS Distributions 	/* pre-BigSur SDK: no vm_remap_new() */
1181*27b03b36SApple OSS Distributions 	T_LOG("No vm_remap_new() to test");
1182*27b03b36SApple OSS Distributions #endif /* defined(VM_MEMORY_ROSETTA) */
1183*27b03b36SApple OSS Distributions 
1184*27b03b36SApple OSS Distributions 	/* test mach_make_memory_entry_64(VM_SHARE) of RO */
1185*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1186*27b03b36SApple OSS Distributions 	remap_size = size;
1187*27b03b36SApple OSS Distributions 	mem_entry = MACH_PORT_NULL;
1188*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
1189*27b03b36SApple OSS Distributions 	    &remap_size,
1190*27b03b36SApple OSS Distributions 	    address,
1191*27b03b36SApple OSS Distributions 	    MAP_MEM_VM_SHARE | VM_PROT_READ | VM_PROT_WRITE,
1192*27b03b36SApple OSS Distributions 	    &mem_entry,
1193*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
1194*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "mach_make_memory_entry_64(VM_SHARE)");
1195*27b03b36SApple OSS Distributions 	if (kr == KERN_PROTECTION_FAILURE) {
1196*27b03b36SApple OSS Distributions 		/* wrong but not a security issue... */
1197*27b03b36SApple OSS Distributions 		goto skip_mem_entry_vm_share_ro;
1198*27b03b36SApple OSS Distributions 	}
1199*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_make_memory_entry_64(VM_SHARE)");
1200*27b03b36SApple OSS Distributions 	remap_address = 0;
1201*27b03b36SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(),
1202*27b03b36SApple OSS Distributions 	    &remap_address,
1203*27b03b36SApple OSS Distributions 	    remap_size,
1204*27b03b36SApple OSS Distributions 	    0,              /* mask */
1205*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1206*27b03b36SApple OSS Distributions 	    mem_entry,
1207*27b03b36SApple OSS Distributions 	    0,              /* offset */
1208*27b03b36SApple OSS Distributions 	    FALSE,              /* copy */
1209*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1210*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1211*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1212*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_map()");
1213*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1214*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1215*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1216*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1217*27b03b36SApple OSS Distributions 	T_LOG("mem_entry(VM_SHARE): 0x%llx 0x%x -> 0x%x", address, before, after);
1218*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before;
1219*27b03b36SApple OSS Distributions 	if (before != after) {
1220*27b03b36SApple OSS Distributions 		T_FAIL("mem_entry(VM_SHARE) bypassed copy-on-write");
1221*27b03b36SApple OSS Distributions 	} else {
1222*27b03b36SApple OSS Distributions 		T_PASS("mem_entry(VM_SHARE) did not bypass copy-on-write");
1223*27b03b36SApple OSS Distributions 	}
1224*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1225*27b03b36SApple OSS Distributions 	tmp_address = address;
1226*27b03b36SApple OSS Distributions 	tmp_size = 0;
1227*27b03b36SApple OSS Distributions 	depth = 99;
1228*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1229*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1230*27b03b36SApple OSS Distributions 	    &tmp_address,
1231*27b03b36SApple OSS Distributions 	    &tmp_size,
1232*27b03b36SApple OSS Distributions 	    &depth,
1233*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1234*27b03b36SApple OSS Distributions 	    &count);
1235*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1236*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1237*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1238*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1239*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1240*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1241*27b03b36SApple OSS Distributions 	    info.object_id);
1242*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1243*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1244*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1245*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_READ, "cur_prot still read-only");
1246*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.max_protection, VM_PROT_READ, "max_prot still read-only");
1247*27b03b36SApple OSS Distributions 	/* check that new mapping is a copy */
1248*27b03b36SApple OSS Distributions 	tmp_address = remap_address;
1249*27b03b36SApple OSS Distributions 	tmp_size = 0;
1250*27b03b36SApple OSS Distributions 	depth = 99;
1251*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1252*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1253*27b03b36SApple OSS Distributions 	    &tmp_address,
1254*27b03b36SApple OSS Distributions 	    &tmp_size,
1255*27b03b36SApple OSS Distributions 	    &depth,
1256*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1257*27b03b36SApple OSS Distributions 	    &count);
1258*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1259*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1260*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1261*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1262*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1263*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1264*27b03b36SApple OSS Distributions 	    info.object_id);
1265*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, remap_address, "address hasn't changed");
1266*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1267*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(depth, 0, "new mapping is unnested");
1268*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_READ, "new cur_prot read-only");
1269*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(info.max_protection, VM_PROT_READ, "new max_prot read-only");
1270*27b03b36SApple OSS Distributions 	/* cleanup */
1271*27b03b36SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), remap_address, remap_size);
1272*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_deallocate()");
1273*27b03b36SApple OSS Distributions 	T_PASS("mem_entry(VM_SHARE) read-only");
1274*27b03b36SApple OSS Distributions skip_mem_entry_vm_share_ro:
1275*27b03b36SApple OSS Distributions 
1276*27b03b36SApple OSS Distributions 	/* test mach_make_memory_entry_64() of RO */
1277*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1278*27b03b36SApple OSS Distributions 	remap_size = size;
1279*27b03b36SApple OSS Distributions 	mem_entry = MACH_PORT_NULL;
1280*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
1281*27b03b36SApple OSS Distributions 	    &remap_size,
1282*27b03b36SApple OSS Distributions 	    address,
1283*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1284*27b03b36SApple OSS Distributions 	    &mem_entry,
1285*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
1286*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(kr, KERN_PROTECTION_FAILURE, "mach_make_memory_entry_64()");
1287*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1288*27b03b36SApple OSS Distributions 	tmp_address = address;
1289*27b03b36SApple OSS Distributions 	tmp_size = 0;
1290*27b03b36SApple OSS Distributions 	depth = 99;
1291*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1292*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1293*27b03b36SApple OSS Distributions 	    &tmp_address,
1294*27b03b36SApple OSS Distributions 	    &tmp_size,
1295*27b03b36SApple OSS Distributions 	    &depth,
1296*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1297*27b03b36SApple OSS Distributions 	    &count);
1298*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1299*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1300*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1301*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1302*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1303*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1304*27b03b36SApple OSS Distributions 	    info.object_id);
1305*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1306*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1307*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1308*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_READ, "cur_prot still read-only");
1309*27b03b36SApple OSS Distributions 	if (depth > 0) {
1310*27b03b36SApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(info.max_protection, VM_PROT_READ, "max_prot still read-only");
1311*27b03b36SApple OSS Distributions 	}
1312*27b03b36SApple OSS Distributions 	T_PASS("mem_entry() read-only");
1313*27b03b36SApple OSS Distributions 
1314*27b03b36SApple OSS Distributions 
1315*27b03b36SApple OSS Distributions 	/*
1316*27b03b36SApple OSS Distributions 	 * Step 2 - check that one can not share write access with a writable
1317*27b03b36SApple OSS Distributions 	 * mapping in the shared region.
1318*27b03b36SApple OSS Distributions 	 */
1319*27b03b36SApple OSS Distributions 	size = 0;
1320*27b03b36SApple OSS Distributions 	for (address = SHARED_REGION_BASE;
1321*27b03b36SApple OSS Distributions 	    address < SHARED_REGION_BASE + SHARED_REGION_SIZE;
1322*27b03b36SApple OSS Distributions 	    address += size) {
1323*27b03b36SApple OSS Distributions 		size = 0;
1324*27b03b36SApple OSS Distributions 		depth = 99;
1325*27b03b36SApple OSS Distributions 		count = VM_REGION_SUBMAP_INFO_COUNT_64;
1326*27b03b36SApple OSS Distributions 		kr = mach_vm_region_recurse(mach_task_self(),
1327*27b03b36SApple OSS Distributions 		    &address,
1328*27b03b36SApple OSS Distributions 		    &size,
1329*27b03b36SApple OSS Distributions 		    &depth,
1330*27b03b36SApple OSS Distributions 		    (vm_region_recurse_info_t)&info,
1331*27b03b36SApple OSS Distributions 		    &count);
1332*27b03b36SApple OSS Distributions 		T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_region_recurse()");
1333*27b03b36SApple OSS Distributions 		if (kr == KERN_INVALID_ADDRESS) {
1334*27b03b36SApple OSS Distributions 			T_SKIP("could not find writable nested mapping");
1335*27b03b36SApple OSS Distributions 			T_END;
1336*27b03b36SApple OSS Distributions 		}
1337*27b03b36SApple OSS Distributions 		T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1338*27b03b36SApple OSS Distributions 		T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1339*27b03b36SApple OSS Distributions 		    address, address + size, depth,
1340*27b03b36SApple OSS Distributions 		    prot_str[info.protection],
1341*27b03b36SApple OSS Distributions 		    prot_str[info.max_protection],
1342*27b03b36SApple OSS Distributions 		    share_mode_str[info.share_mode],
1343*27b03b36SApple OSS Distributions 		    info.object_id);
1344*27b03b36SApple OSS Distributions 		if (depth > 0 && (info.protection & VM_PROT_WRITE)) {
1345*27b03b36SApple OSS Distributions 			/* nested and writable: bingo! */
1346*27b03b36SApple OSS Distributions 			break;
1347*27b03b36SApple OSS Distributions 		}
1348*27b03b36SApple OSS Distributions 	}
1349*27b03b36SApple OSS Distributions 	if (address >= SHARED_REGION_BASE + SHARED_REGION_SIZE) {
1350*27b03b36SApple OSS Distributions 		T_SKIP("could not find writable nested mapping");
1351*27b03b36SApple OSS Distributions 		T_END;
1352*27b03b36SApple OSS Distributions 	}
1353*27b03b36SApple OSS Distributions 
1354*27b03b36SApple OSS Distributions 	/* test vm_remap() of RW */
1355*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1356*27b03b36SApple OSS Distributions 	remap_address = 0;
1357*27b03b36SApple OSS Distributions 	remap_size = size;
1358*27b03b36SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
1359*27b03b36SApple OSS Distributions 	    &remap_address,
1360*27b03b36SApple OSS Distributions 	    remap_size,
1361*27b03b36SApple OSS Distributions 	    0,
1362*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR,
1363*27b03b36SApple OSS Distributions 	    mach_task_self(),
1364*27b03b36SApple OSS Distributions 	    address,
1365*27b03b36SApple OSS Distributions 	    FALSE,
1366*27b03b36SApple OSS Distributions 	    &cur_prot,
1367*27b03b36SApple OSS Distributions 	    &max_prot,
1368*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1369*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_remap()");
1370*27b03b36SApple OSS Distributions 	if (!(cur_prot & VM_PROT_WRITE)) {
1371*27b03b36SApple OSS Distributions 		T_LOG("vm_remap(): 0x%llx not writable %s/%s",
1372*27b03b36SApple OSS Distributions 		    remap_address, prot_str[cur_prot], prot_str[max_prot]);
1373*27b03b36SApple OSS Distributions 		T_ASSERT_FAIL("vm_remap() remapping not writable");
1374*27b03b36SApple OSS Distributions 	}
1375*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1376*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1377*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1378*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1379*27b03b36SApple OSS Distributions 	T_LOG("vm_remap(): 0x%llx 0x%x -> 0x%x", address, before, after);
1380*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before;
1381*27b03b36SApple OSS Distributions 	if (before != after) {
1382*27b03b36SApple OSS Distributions 		T_FAIL("vm_remap() bypassed copy-on-write");
1383*27b03b36SApple OSS Distributions 	} else {
1384*27b03b36SApple OSS Distributions 		T_PASS("vm_remap() did not bypass copy-on-write");
1385*27b03b36SApple OSS Distributions 	}
1386*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1387*27b03b36SApple OSS Distributions 	tmp_address = address;
1388*27b03b36SApple OSS Distributions 	tmp_size = 0;
1389*27b03b36SApple OSS Distributions 	depth = 99;
1390*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1391*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1392*27b03b36SApple OSS Distributions 	    &tmp_address,
1393*27b03b36SApple OSS Distributions 	    &tmp_size,
1394*27b03b36SApple OSS Distributions 	    &depth,
1395*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1396*27b03b36SApple OSS Distributions 	    &count);
1397*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1398*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1399*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1400*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1401*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1402*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1403*27b03b36SApple OSS Distributions 	    info.object_id);
1404*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1405*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1406*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1407*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_DEFAULT, "cur_prot still writable");
1408*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ((info.max_protection & VM_PROT_WRITE), VM_PROT_WRITE, "max_prot still writable");
1409*27b03b36SApple OSS Distributions 	/* cleanup */
1410*27b03b36SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), remap_address, remap_size);
1411*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_deallocate()");
1412*27b03b36SApple OSS Distributions 
1413*27b03b36SApple OSS Distributions #if defined(VM_MEMORY_ROSETTA)
1414*27b03b36SApple OSS Distributions 	if (dlsym(RTLD_DEFAULT, "mach_vm_remap_new") == NULL) {
1415*27b03b36SApple OSS Distributions 		T_PASS("vm_remap_new() is not present");
1416*27b03b36SApple OSS Distributions 		goto skip_vm_remap_new_rw;
1417*27b03b36SApple OSS Distributions 	}
1418*27b03b36SApple OSS Distributions 	/* test vm_remap_new() of RW */
1419*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1420*27b03b36SApple OSS Distributions 	remap_address = 0;
1421*27b03b36SApple OSS Distributions 	remap_size = size;
1422*27b03b36SApple OSS Distributions 	cur_prot = VM_PROT_READ | VM_PROT_WRITE;
1423*27b03b36SApple OSS Distributions 	max_prot = VM_PROT_READ | VM_PROT_WRITE;
1424*27b03b36SApple OSS Distributions 	kr = mach_vm_remap_new(mach_task_self(),
1425*27b03b36SApple OSS Distributions 	    &remap_address,
1426*27b03b36SApple OSS Distributions 	    remap_size,
1427*27b03b36SApple OSS Distributions 	    0,
1428*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1429*27b03b36SApple OSS Distributions 	    mach_task_self(),
1430*27b03b36SApple OSS Distributions 	    address,
1431*27b03b36SApple OSS Distributions 	    FALSE,
1432*27b03b36SApple OSS Distributions 	    &cur_prot,
1433*27b03b36SApple OSS Distributions 	    &max_prot,
1434*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1435*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_remap_new()");
1436*27b03b36SApple OSS Distributions 	if (kr == KERN_PROTECTION_FAILURE) {
1437*27b03b36SApple OSS Distributions 		/* wrong but not a security issue... */
1438*27b03b36SApple OSS Distributions 		goto skip_vm_remap_new_rw;
1439*27b03b36SApple OSS Distributions 	}
1440*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_remap_new()");
1441*27b03b36SApple OSS Distributions 	if (!(cur_prot & VM_PROT_WRITE)) {
1442*27b03b36SApple OSS Distributions 		T_LOG("vm_remap_new(): 0x%llx not writable %s/%s",
1443*27b03b36SApple OSS Distributions 		    remap_address, prot_str[cur_prot], prot_str[max_prot]);
1444*27b03b36SApple OSS Distributions 		T_ASSERT_FAIL("vm_remap_new() remapping not writable");
1445*27b03b36SApple OSS Distributions 	}
1446*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1447*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1448*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1449*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1450*27b03b36SApple OSS Distributions 	T_LOG("vm_remap_new(): 0x%llx 0x%x -> 0x%x", address, before, after);
1451*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before;
1452*27b03b36SApple OSS Distributions 	if (before != after) {
1453*27b03b36SApple OSS Distributions 		T_FAIL("vm_remap_new() bypassed copy-on-write");
1454*27b03b36SApple OSS Distributions 	} else {
1455*27b03b36SApple OSS Distributions 		T_PASS("vm_remap_new() did not bypass copy-on-write");
1456*27b03b36SApple OSS Distributions 	}
1457*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1458*27b03b36SApple OSS Distributions 	tmp_address = address;
1459*27b03b36SApple OSS Distributions 	tmp_size = 0;
1460*27b03b36SApple OSS Distributions 	depth = 99;
1461*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1462*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1463*27b03b36SApple OSS Distributions 	    &tmp_address,
1464*27b03b36SApple OSS Distributions 	    &tmp_size,
1465*27b03b36SApple OSS Distributions 	    &depth,
1466*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1467*27b03b36SApple OSS Distributions 	    &count);
1468*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1469*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1470*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1471*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1472*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1473*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1474*27b03b36SApple OSS Distributions 	    info.object_id);
1475*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1476*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1477*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1478*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_DEFAULT, "cur_prot still writable");
1479*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ((info.max_protection & VM_PROT_WRITE), VM_PROT_WRITE, "max_prot still writable");
1480*27b03b36SApple OSS Distributions 	/* cleanup */
1481*27b03b36SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), remap_address, remap_size);
1482*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_deallocate()");
1483*27b03b36SApple OSS Distributions skip_vm_remap_new_rw:
1484*27b03b36SApple OSS Distributions #else /* defined(VM_MEMORY_ROSETTA) */
1485*27b03b36SApple OSS Distributions 	/* pre-BigSur SDK: no vm_remap_new() */
1486*27b03b36SApple OSS Distributions 	T_LOG("No vm_remap_new() to test");
1487*27b03b36SApple OSS Distributions #endif /* defined(VM_MEMORY_ROSETTA) */
1488*27b03b36SApple OSS Distributions 
1489*27b03b36SApple OSS Distributions 	/* test mach_make_memory_entry_64(VM_SHARE) of RW */
1490*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1491*27b03b36SApple OSS Distributions 	remap_size = size;
1492*27b03b36SApple OSS Distributions 	mem_entry = MACH_PORT_NULL;
1493*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
1494*27b03b36SApple OSS Distributions 	    &remap_size,
1495*27b03b36SApple OSS Distributions 	    address,
1496*27b03b36SApple OSS Distributions 	    MAP_MEM_VM_SHARE | VM_PROT_READ | VM_PROT_WRITE,
1497*27b03b36SApple OSS Distributions 	    &mem_entry,
1498*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
1499*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "mach_make_memory_entry_64(VM_SHARE)");
1500*27b03b36SApple OSS Distributions 	if (kr == KERN_PROTECTION_FAILURE) {
1501*27b03b36SApple OSS Distributions 		/* wrong but not a security issue... */
1502*27b03b36SApple OSS Distributions 		goto skip_mem_entry_vm_share_rw;
1503*27b03b36SApple OSS Distributions 	}
1504*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_make_memory_entry_64(VM_SHARE)");
1505*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap_size, size, "mem_entry(VM_SHARE) should cover whole mapping");
1506*27b03b36SApple OSS Distributions //	T_LOG("AFTER MAKE_MEM_ENTRY(VM_SHARE) 0x%llx...", address); fflush(stdout); fflush(stderr); getchar();
1507*27b03b36SApple OSS Distributions 	remap_address = 0;
1508*27b03b36SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(),
1509*27b03b36SApple OSS Distributions 	    &remap_address,
1510*27b03b36SApple OSS Distributions 	    remap_size,
1511*27b03b36SApple OSS Distributions 	    0,              /* mask */
1512*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1513*27b03b36SApple OSS Distributions 	    mem_entry,
1514*27b03b36SApple OSS Distributions 	    0,              /* offset */
1515*27b03b36SApple OSS Distributions 	    FALSE,              /* copy */
1516*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1517*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1518*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1519*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_map()");
1520*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1521*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1522*27b03b36SApple OSS Distributions //	T_LOG("AFTER VM_MAP 0x%llx...", remap_address); fflush(stdout); fflush(stderr); getchar();
1523*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1524*27b03b36SApple OSS Distributions //	T_LOG("AFTER WRITE 0x%llx...", remap_address); fflush(stdout); fflush(stderr); getchar();
1525*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1526*27b03b36SApple OSS Distributions 	T_LOG("mem_entry(VM_SHARE): 0x%llx 0x%x -> 0x%x", address, before, after);
1527*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before;
1528*27b03b36SApple OSS Distributions 	if (before != after) {
1529*27b03b36SApple OSS Distributions 		T_FAIL("mem_entry(VM_SHARE) bypassed copy-on-write");
1530*27b03b36SApple OSS Distributions 	} else {
1531*27b03b36SApple OSS Distributions 		T_PASS("mem_entry(VM_SHARE) did not bypass copy-on-write");
1532*27b03b36SApple OSS Distributions 	}
1533*27b03b36SApple OSS Distributions 	/* check that region is still nested */
1534*27b03b36SApple OSS Distributions 	tmp_address = address;
1535*27b03b36SApple OSS Distributions 	tmp_size = 0;
1536*27b03b36SApple OSS Distributions 	depth = 99;
1537*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1538*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1539*27b03b36SApple OSS Distributions 	    &tmp_address,
1540*27b03b36SApple OSS Distributions 	    &tmp_size,
1541*27b03b36SApple OSS Distributions 	    &depth,
1542*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1543*27b03b36SApple OSS Distributions 	    &count);
1544*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1545*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1546*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1547*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1548*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1549*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1550*27b03b36SApple OSS Distributions 	    info.object_id);
1551*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1552*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1553*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_GT(depth, 0, "still nested");
1554*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_DEFAULT, "cur_prot still writable");
1555*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ((info.max_protection & VM_PROT_WRITE), VM_PROT_WRITE, "max_prot still writable");
1556*27b03b36SApple OSS Distributions 	/* cleanup */
1557*27b03b36SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), remap_address, remap_size);
1558*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_deallocate()");
1559*27b03b36SApple OSS Distributions 	mach_port_deallocate(mach_task_self(), mem_entry);
1560*27b03b36SApple OSS Distributions skip_mem_entry_vm_share_rw:
1561*27b03b36SApple OSS Distributions 
1562*27b03b36SApple OSS Distributions 	/* test mach_make_memory_entry_64() of RW */
1563*27b03b36SApple OSS Distributions 	before = *(uint32_t *)(uintptr_t)address;
1564*27b03b36SApple OSS Distributions 	remap_size = size;
1565*27b03b36SApple OSS Distributions 	mem_entry = MACH_PORT_NULL;
1566*27b03b36SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
1567*27b03b36SApple OSS Distributions 	    &remap_size,
1568*27b03b36SApple OSS Distributions 	    address,
1569*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1570*27b03b36SApple OSS Distributions 	    &mem_entry,
1571*27b03b36SApple OSS Distributions 	    MACH_PORT_NULL);
1572*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_make_memory_entry_64()");
1573*27b03b36SApple OSS Distributions 	remap_address = 0;
1574*27b03b36SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(),
1575*27b03b36SApple OSS Distributions 	    &remap_address,
1576*27b03b36SApple OSS Distributions 	    remap_size,
1577*27b03b36SApple OSS Distributions 	    0,              /* mask */
1578*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1579*27b03b36SApple OSS Distributions 	    mem_entry,
1580*27b03b36SApple OSS Distributions 	    0,              /* offset */
1581*27b03b36SApple OSS Distributions 	    FALSE,              /* copy */
1582*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1583*27b03b36SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1584*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1585*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_map()");
1586*27b03b36SApple OSS Distributions 	remap = *(uint32_t *)(uintptr_t)remap_address;
1587*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(remap, before, "remap matches original");
1588*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before + 1;
1589*27b03b36SApple OSS Distributions 	after = *(uint32_t *)(uintptr_t)address;
1590*27b03b36SApple OSS Distributions 	T_LOG("mem_entry(): 0x%llx 0x%x -> 0x%x", address, before, after);
1591*27b03b36SApple OSS Distributions 	*(uint32_t *)(uintptr_t)remap_address = before;
1592*27b03b36SApple OSS Distributions 	/* check that region is no longer nested */
1593*27b03b36SApple OSS Distributions 	tmp_address = address;
1594*27b03b36SApple OSS Distributions 	tmp_size = 0;
1595*27b03b36SApple OSS Distributions 	depth = 99;
1596*27b03b36SApple OSS Distributions 	count = VM_REGION_SUBMAP_INFO_COUNT_64;
1597*27b03b36SApple OSS Distributions 	kr = mach_vm_region_recurse(mach_task_self(),
1598*27b03b36SApple OSS Distributions 	    &tmp_address,
1599*27b03b36SApple OSS Distributions 	    &tmp_size,
1600*27b03b36SApple OSS Distributions 	    &depth,
1601*27b03b36SApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1602*27b03b36SApple OSS Distributions 	    &count);
1603*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse()");
1604*27b03b36SApple OSS Distributions 	T_LOG("0x%llx - 0x%llx depth:%d %s/%s %s 0x%x",
1605*27b03b36SApple OSS Distributions 	    tmp_address, tmp_address + tmp_size, depth,
1606*27b03b36SApple OSS Distributions 	    prot_str[info.protection],
1607*27b03b36SApple OSS Distributions 	    prot_str[info.max_protection],
1608*27b03b36SApple OSS Distributions 	    share_mode_str[info.share_mode],
1609*27b03b36SApple OSS Distributions 	    info.object_id);
1610*27b03b36SApple OSS Distributions 	if (before != after) {
1611*27b03b36SApple OSS Distributions 		if (depth == 0) {
1612*27b03b36SApple OSS Distributions 			T_PASS("mem_entry() honored copy-on-write");
1613*27b03b36SApple OSS Distributions 		} else {
1614*27b03b36SApple OSS Distributions 			T_FAIL("mem_entry() did not trigger copy-on_write");
1615*27b03b36SApple OSS Distributions 		}
1616*27b03b36SApple OSS Distributions 	} else {
1617*27b03b36SApple OSS Distributions 		T_FAIL("mem_entry() did not honor copy-on-write");
1618*27b03b36SApple OSS Distributions 	}
1619*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(tmp_address, address, "address hasn't changed");
1620*27b03b36SApple OSS Distributions //	T_QUIET; T_ASSERT_EQ(tmp_size, size, "size hasn't changed");
1621*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(depth, 0, "no longer nested");
1622*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(info.protection, VM_PROT_DEFAULT, "cur_prot still writable");
1623*27b03b36SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ((info.max_protection & VM_PROT_WRITE), VM_PROT_WRITE, "max_prot still writable");
1624*27b03b36SApple OSS Distributions 	/* cleanup */
1625*27b03b36SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), remap_address, remap_size);
1626*27b03b36SApple OSS Distributions 	T_QUIET; T_EXPECT_MACH_SUCCESS(kr, "vm_deallocate()");
1627*27b03b36SApple OSS Distributions 	mach_port_deallocate(mach_task_self(), mem_entry);
1628*27b03b36SApple OSS Distributions }
1629*27b03b36SApple OSS Distributions 
1630*27b03b36SApple OSS Distributions T_DECL(copyoverwrite_submap_protection, "test copywrite vm region submap \
1631*27b03b36SApple OSS Distributions     protection", T_META_ALL_VALID_ARCHS(true))
1632*27b03b36SApple OSS Distributions {
1633*27b03b36SApple OSS Distributions 	kern_return_t           kr;
1634*27b03b36SApple OSS Distributions 	mach_vm_address_t       vmaddr;
1635*27b03b36SApple OSS Distributions 	mach_vm_size_t          vmsize;
1636*27b03b36SApple OSS Distributions 	natural_t               depth;
1637*27b03b36SApple OSS Distributions 	vm_region_submap_short_info_data_64_t region_info;
1638*27b03b36SApple OSS Distributions 	mach_msg_type_number_t  region_info_count;
1639*27b03b36SApple OSS Distributions 
1640*27b03b36SApple OSS Distributions 	for (vmaddr = SHARED_REGION_BASE;
1641*27b03b36SApple OSS Distributions 	    vmaddr < SHARED_REGION_BASE + SHARED_REGION_SIZE;
1642*27b03b36SApple OSS Distributions 	    vmaddr += vmsize) {
1643*27b03b36SApple OSS Distributions 		depth = 99;
1644*27b03b36SApple OSS Distributions 		region_info_count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
1645*27b03b36SApple OSS Distributions 		kr = mach_vm_region_recurse(mach_task_self(),
1646*27b03b36SApple OSS Distributions 		    &vmaddr,
1647*27b03b36SApple OSS Distributions 		    &vmsize,
1648*27b03b36SApple OSS Distributions 		    &depth,
1649*27b03b36SApple OSS Distributions 		    (vm_region_info_t) &region_info,
1650*27b03b36SApple OSS Distributions 		    &region_info_count);
1651*27b03b36SApple OSS Distributions 		if (kr == KERN_INVALID_ADDRESS) {
1652*27b03b36SApple OSS Distributions 			break;
1653*27b03b36SApple OSS Distributions 		}
1654*27b03b36SApple OSS Distributions 		T_ASSERT_MACH_SUCCESS(kr, "vm_region_recurse(0x%llx)", vmaddr);
1655*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(region_info_count,
1656*27b03b36SApple OSS Distributions 		    VM_REGION_SUBMAP_SHORT_INFO_COUNT_64,
1657*27b03b36SApple OSS Distributions 		    "vm_region_recurse(0x%llx) count = %d expected %d",
1658*27b03b36SApple OSS Distributions 		    vmaddr, region_info_count,
1659*27b03b36SApple OSS Distributions 		    VM_REGION_SUBMAP_SHORT_INFO_COUNT_64);
1660*27b03b36SApple OSS Distributions 
1661*27b03b36SApple OSS Distributions 		T_LOG("--> region: vmaddr 0x%llx depth %d prot 0x%x/0x%x",
1662*27b03b36SApple OSS Distributions 		    vmaddr, depth, region_info.protection,
1663*27b03b36SApple OSS Distributions 		    region_info.max_protection);
1664*27b03b36SApple OSS Distributions 		if (depth == 0) {
1665*27b03b36SApple OSS Distributions 			/* not a submap mapping: next mapping */
1666*27b03b36SApple OSS Distributions 			continue;
1667*27b03b36SApple OSS Distributions 		}
1668*27b03b36SApple OSS Distributions 		if (vmaddr >= SHARED_REGION_BASE + SHARED_REGION_SIZE) {
1669*27b03b36SApple OSS Distributions 			break;
1670*27b03b36SApple OSS Distributions 		}
1671*27b03b36SApple OSS Distributions 		kr = mach_vm_copy(mach_task_self(),
1672*27b03b36SApple OSS Distributions 		    vmaddr,
1673*27b03b36SApple OSS Distributions 		    vmsize,
1674*27b03b36SApple OSS Distributions 		    vmaddr);
1675*27b03b36SApple OSS Distributions 		if (kr == KERN_PROTECTION_FAILURE ||
1676*27b03b36SApple OSS Distributions 		    kr == KERN_INVALID_ADDRESS) {
1677*27b03b36SApple OSS Distributions 			T_PASS("vm_copy(0x%llx,0x%llx) expected prot error 0x%x (%s)",
1678*27b03b36SApple OSS Distributions 			    vmaddr, vmsize, kr, mach_error_string(kr));
1679*27b03b36SApple OSS Distributions 			continue;
1680*27b03b36SApple OSS Distributions 		}
1681*27b03b36SApple OSS Distributions 		T_ASSERT_MACH_SUCCESS(kr, "vm_copy(0x%llx,0x%llx) prot 0x%x",
1682*27b03b36SApple OSS Distributions 		    vmaddr, vmsize, region_info.protection);
1683*27b03b36SApple OSS Distributions 		depth = 0;
1684*27b03b36SApple OSS Distributions 		region_info_count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
1685*27b03b36SApple OSS Distributions 		kr = mach_vm_region_recurse(mach_task_self(),
1686*27b03b36SApple OSS Distributions 		    &vmaddr,
1687*27b03b36SApple OSS Distributions 		    &vmsize,
1688*27b03b36SApple OSS Distributions 		    &depth,
1689*27b03b36SApple OSS Distributions 		    (vm_region_info_t) &region_info,
1690*27b03b36SApple OSS Distributions 		    &region_info_count);
1691*27b03b36SApple OSS Distributions 		T_ASSERT_MACH_SUCCESS(kr, "m_region_recurse(0x%llx)", vmaddr);
1692*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(region_info_count,
1693*27b03b36SApple OSS Distributions 		    VM_REGION_SUBMAP_SHORT_INFO_COUNT_64,
1694*27b03b36SApple OSS Distributions 		    "vm_region_recurse() count = %d expected %d",
1695*27b03b36SApple OSS Distributions 		    region_info_count, VM_REGION_SUBMAP_SHORT_INFO_COUNT_64);
1696*27b03b36SApple OSS Distributions 
1697*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(depth, 0, "vm_region_recurse(0x%llx): depth = %d expected 0",
1698*27b03b36SApple OSS Distributions 		    vmaddr, depth);
1699*27b03b36SApple OSS Distributions 		T_ASSERT_EQ((region_info.protection & VM_PROT_EXECUTE),
1700*27b03b36SApple OSS Distributions 		    0, "vm_region_recurse(0x%llx): prot 0x%x",
1701*27b03b36SApple OSS Distributions 		    vmaddr, region_info.protection);
1702*27b03b36SApple OSS Distributions 	}
1703*27b03b36SApple OSS Distributions }
1704*27b03b36SApple OSS Distributions 
1705*27b03b36SApple OSS Distributions T_DECL(wire_text, "test wired text for rdar://problem/16783546 Wiring code in \
1706*27b03b36SApple OSS Distributions     the shared region triggers code-signing violations",
1707*27b03b36SApple OSS Distributions     T_META_ALL_VALID_ARCHS(true))
1708*27b03b36SApple OSS Distributions {
1709*27b03b36SApple OSS Distributions 	uint32_t *addr, before, after;
1710*27b03b36SApple OSS Distributions 	int retval;
1711*27b03b36SApple OSS Distributions 	int saved_errno;
1712*27b03b36SApple OSS Distributions 	kern_return_t kr;
1713*27b03b36SApple OSS Distributions 	vm_address_t map_addr, remap_addr;
1714*27b03b36SApple OSS Distributions 	vm_prot_t curprot, maxprot;
1715*27b03b36SApple OSS Distributions 
1716*27b03b36SApple OSS Distributions 	addr = (uint32_t *)&printf;
1717*27b03b36SApple OSS Distributions #if __has_feature(ptrauth_calls)
1718*27b03b36SApple OSS Distributions 	map_addr = (vm_address_t)(uintptr_t)ptrauth_strip(addr, ptrauth_key_function_pointer);
1719*27b03b36SApple OSS Distributions #else /* __has_feature(ptrauth_calls) */
1720*27b03b36SApple OSS Distributions 	map_addr = (vm_address_t)(uintptr_t)addr;
1721*27b03b36SApple OSS Distributions #endif /* __has_feature(ptrauth_calls) */
1722*27b03b36SApple OSS Distributions 	remap_addr = 0;
1723*27b03b36SApple OSS Distributions 	kr = vm_remap(mach_task_self(), &remap_addr, 4096,
1724*27b03b36SApple OSS Distributions 	    0,           /* mask */
1725*27b03b36SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1726*27b03b36SApple OSS Distributions 	    mach_task_self(), map_addr,
1727*27b03b36SApple OSS Distributions 	    FALSE,           /* copy */
1728*27b03b36SApple OSS Distributions 	    &curprot, &maxprot,
1729*27b03b36SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1730*27b03b36SApple OSS Distributions 	T_ASSERT_EQ(kr, KERN_SUCCESS, "vm_remap error 0x%x (%s)",
1731*27b03b36SApple OSS Distributions 	    kr, mach_error_string(kr));
1732*27b03b36SApple OSS Distributions 	before = *addr;
1733*27b03b36SApple OSS Distributions 	retval = mlock(addr, 4096);
1734*27b03b36SApple OSS Distributions 	after = *addr;
1735*27b03b36SApple OSS Distributions 	if (retval != 0) {
1736*27b03b36SApple OSS Distributions 		saved_errno = errno;
1737*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(saved_errno, EACCES, "wire shared text error %d (%s), expected: %d",
1738*27b03b36SApple OSS Distributions 		    saved_errno, strerror(saved_errno), EACCES);
1739*27b03b36SApple OSS Distributions 	} else if (after != before) {
1740*27b03b36SApple OSS Distributions 		T_ASSERT_FAIL("shared text changed by wiring at %p 0x%x -> 0x%x", addr, before, after);
1741*27b03b36SApple OSS Distributions 	} else {
1742*27b03b36SApple OSS Distributions 		T_PASS("wire shared text");
1743*27b03b36SApple OSS Distributions 	}
1744*27b03b36SApple OSS Distributions 
1745*27b03b36SApple OSS Distributions 	addr = (uint32_t *) &fprintf;
1746*27b03b36SApple OSS Distributions 	before = *addr;
1747*27b03b36SApple OSS Distributions 	retval = mlock(addr, 4096);
1748*27b03b36SApple OSS Distributions 	after = *addr;
1749*27b03b36SApple OSS Distributions 	if (retval != 0) {
1750*27b03b36SApple OSS Distributions 		saved_errno = errno;
1751*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(saved_errno, EACCES, "wire shared text error %d (%s), expected: %d",
1752*27b03b36SApple OSS Distributions 		    saved_errno, strerror(saved_errno), EACCES);
1753*27b03b36SApple OSS Distributions 	} else if (after != before) {
1754*27b03b36SApple OSS Distributions 		T_ASSERT_FAIL("shared text changed by wiring at %p 0x%x -> 0x%x", addr, before, after);
1755*27b03b36SApple OSS Distributions 	} else {
1756*27b03b36SApple OSS Distributions 		T_PASS("wire shared text");
1757*27b03b36SApple OSS Distributions 	}
1758*27b03b36SApple OSS Distributions 
1759*27b03b36SApple OSS Distributions 	addr = (uint32_t *) &testmain_wire_text;
1760*27b03b36SApple OSS Distributions 	before = *addr;
1761*27b03b36SApple OSS Distributions 	retval = mlock(addr, 4096);
1762*27b03b36SApple OSS Distributions 	after = *addr;
1763*27b03b36SApple OSS Distributions 	if (retval != 0) {
1764*27b03b36SApple OSS Distributions 		saved_errno = errno;
1765*27b03b36SApple OSS Distributions 		T_ASSERT_EQ(saved_errno, EACCES, "wire text error return error %d (%s)",
1766*27b03b36SApple OSS Distributions 		    saved_errno, strerror(saved_errno));
1767*27b03b36SApple OSS Distributions 	} else if (after != before) {
1768*27b03b36SApple OSS Distributions 		T_ASSERT_FAIL("text changed by wiring at %p 0x%x -> 0x%x", addr, before, after);
1769*27b03b36SApple OSS Distributions 	} else {
1770*27b03b36SApple OSS Distributions 		T_PASS("wire text");
1771*27b03b36SApple OSS Distributions 	}
1772*27b03b36SApple OSS Distributions }
1773