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