]> git.saurik.com Git - apple/xnu.git/blame - tests/vm_memory_tests_src/vm_tests.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / vm_memory_tests_src / vm_tests.c
CommitLineData
f427ee49
A
1//
2// vmremaptest.c
3//
4// Created by Lionel Desai on 9/16/19.
5// Copyright © 2019 Apple. All rights reserved.
6//
7
8#include "mach_vm_tests.h"
9#include <sys/sysctl.h>
10
11
12#define TESTSZ (140 * 1024 * 1024ULL)
13
14void
15mach_vm_client(mach_port_t port)
16{
17 mach_port_t memport = MACH_PORT_NULL;
18 mach_vm_address_t src = 0, dest = 0, tmp = 0;
19 mach_vm_size_t size = 0;
20 vm_prot_t cur_prot, max_prot;
21 mach_port_name_t lport = 0;
22 kern_return_t ret = 0;
23 boolean_t copy = FALSE;
24 mach_vm_offset_t misoffset = 0;
25
26 mach_msg_type_number_t countp;
27 mach_msg_size_t messageSize = 0;
28 ipc_message_t *message = NULL;
29
30 char buffer[PATH_MAX];
31 ret = proc_pidpath(getpid(), buffer, sizeof(buffer));
32 assert(ret != -1);
33
34 messageSize = sizeof(ipc_message_t) + sizeof(mach_msg_trailer_t) + 64;
35 message = (ipc_message_t *)calloc(1, messageSize);
36
37 message->header.msgh_bits = MACH_MSGH_BITS_ZERO;
38 message->header.msgh_size = messageSize;
39 message->header.msgh_remote_port = MACH_PORT_NULL;
40 message->header.msgh_local_port = port;
41
42 while (1) {
43 /* Awaiting the pid/src. addr/size from the server so we know what to remap from where */
44 ret = mach_msg(&message->header, MACH_RCV_MSG | MACH_RCV_LARGE, 0, messageSize, port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
45 if (ret == KERN_SUCCESS) {
46 if (debug) {
47 T_LOG("CLIENT: received info from server... 0x%llx, %lld, 0x%llx, %d - %d\n", message->address, message->size, message->misoffset, message->vm_op, message->copy);
48 }
49
50 switch (message->vm_op) {
51 case VM_OP_REMAP:
52 ret = task_for_pid(mach_task_self(), (pid_t) message->pid, &lport);
53 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "task_for_pid");
54
55 copy = message->copy;
56 size = message->size;
57 src = message->address;
58 misoffset = 0;
59
60 ret = mach_vm_allocate(mach_task_self(), &tmp, size + 16384, VM_FLAGS_ANYWHERE);
61 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "mach_vm_allocate");
62 mach_vm_deallocate(mach_task_self(), tmp, size + 16384);
63
64 dest = tmp + 4096;
65
66 ret = mach_vm_remap(mach_task_self(), &dest, size, 0, VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR,
67 lport, src, copy,
68 &cur_prot,
69 &max_prot,
70 VM_INHERIT_NONE);
71
72 if (ret) {
73 char dstval[64];
74 memcpy(dstval, (void*) dest, 64);
75 T_LOG("CLIENT: mach_vm_remap FAILED: %s -- src 0x%llx, dest 0x%llx (%s)\n", mach_error_string(ret), src, dest, dstval);
76 T_FAIL("CLIENT: mach_vm_remap FAILED");
77 }
78
79 memcpy(message->value, (void*)dest, 64);
80 break;
81
82 case VM_OP_READ_OVERWRITE:
83 ret = task_for_pid(mach_task_self(), (pid_t) message->pid, &lport);
84 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "task_for_pid");
85
86 size = message->size;
87 src = message->address;
88 misoffset = 0;
89
90 mach_vm_size_t dest_size = 0;
91 ret = mach_vm_allocate(mach_task_self(), &tmp, size + 16384, VM_FLAGS_ANYWHERE);
92 assert(KERN_SUCCESS == ret);
93
94 dest = tmp + 4096;
95
96 ret = mach_vm_read_overwrite(lport, src, size, dest, &dest_size);
97
98 if (ret) {
99 char dstval[64];
100 memcpy(dstval, (void*) dest, 64);
101 T_LOG("CLIENT: mach_vm_read_overwrite FAILED: %s -- src 0x%llx, dest 0x%llx (%s)\n", mach_error_string(ret), src, dest, dstval);
102 T_FAIL("CLIENT: mach_vm_read_overwrite FAILED");
103 }
104
105 memcpy(message->value, (void*)dest, 64);
106 break;
107
108 case VM_OP_READ:
109 ret = task_for_pid(mach_task_self(), (pid_t) message->pid, &lport);
110 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "task_for_pid");
111
112 size = message->size;
113 src = message->address;
114 misoffset = 0;
115
116 ret = mach_vm_read(lport, src, size, (vm_offset_t*)&dest, &countp);
117 if (ret) {
118 char dstval[64];
119 memcpy(dstval, (void*) dest, 64);
120 T_LOG("CLIENT: mach_vm_read FAILED: %s -- src 0x%llx, dest 0x%llx (%s)\n", mach_error_string(ret), src, dest, dstval);
121 T_FAIL("CLIENT: mach_vm_read FAILED");
122 exit(1);
123 }
124
125 memcpy(message->value, (void*)dest, 64);
126 break;
127
128#if 0
129 case VM_OP_WRITE:
130 ret = task_for_pid(mach_task_self(), (pid_t) message->pid, &lport);
131 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "task_for_pid");
132
133 size = message->size;
134 src = message->address;
135 misoffset = 0;
136
137 ret = mach_vm_write(lport, src, dest, countp);
138 if (ret) {
139 char dstval[64];
140 memcpy(dstval, (void*) dest, 64);
141 T_LOG("CLIENT: mach_vm_write FAILED: %s -- src 0x%llx, dest 0x%llx (%s)\n", mach_error_string(ret), src, dest, dstval);
142 T_FAIL("CLIENT: mach_vm_write FAILED");
143 }
144
145 memcpy(message->value, (void*)dest, 64);
146 break;
147#endif
148 case VM_OP_MEMENTRY:
149 assert(message->body.msgh_descriptor_count == 1);
150 dest = 0;
151 size = message->size;
152 memport = message->port_descriptor.name;
153 copy = message->copy;
154 if (copy) {
155 misoffset = 0;
156 } else {
157 misoffset = message->misoffset;
158 }
159
160 cur_prot = max_prot = VM_PROT_READ;
161#if 0
162 /* This + VM_FLAGS_FIXED in mach_vm_map() will return KERN_INVALID_ARG expectedly */
163 ret = mach_vm_allocate(mach_task_self(), &tmp, size + 16384, VM_FLAGS_ANYWHERE);
164 dest = tmp + 4095;
165 mach_vm_deallocate(mach_task_self(), tmp, size + 16384);
166#endif
167 ret = mach_vm_map(mach_task_self(), &dest, size, 0 /*mask*/,
168 VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR,
169 memport, 0 /*offset*/, copy, cur_prot, max_prot, VM_INHERIT_NONE);
170
171 if (ret) {
172 T_LOG("CLIENT: mach_vm_map FAILED: %s -- port 0x%x\n", mach_error_string(ret), memport);
173 T_FAIL("CLIENT: mach_vm_map FAILED");
174 }
175
176 memcpy(message->value, (void*)(dest + misoffset), 64);
177 break;
178
179 case VM_OP_UNMAP:
180 assert(dest);
181 ret = mach_vm_deallocate(mach_task_self(), dest, size);
182 if (ret) {
183 T_LOG("CLIENT: mach_vm_deallocate FAILED: %s -- dest 0x%llx, size 0x%llx\n", mach_error_string(ret), dest, size);
184 T_FAIL("CLIENT: mach_vm_deallocate FAILED");
185 }
186 /* No message to send here */
187 continue;
188
189 case VM_OP_NONE:
190 memcpy(message->value, (void*) (dest + misoffset), 64);
191 break;
192
193 case VM_OP_EXIT:
194 if (debug) {
195 T_LOG("CLIENT EXITING ****** \n");
196 }
197 return;
198
199 case VM_OP_EXIT_ERROR:
200 if (debug) {
201 T_LOG("CLIENT EXITING WITH ERROR****** \n");
202 T_FAIL("Revieved VM_OP_EXIT_ERROR");
203 }
204 return;
205 default:
206 break;
207 }
208
209 char dstval[64];
210 memcpy(dstval, (void*) message->value, 64);
211 dstval[63] = '\0';
212
213 if (debug) {
214 T_LOG("CLIENT: dest 0x%llx -> 0x%llx (0x%llx), *dest %s\n", dest, dest + misoffset, misoffset, dstval);
215 /*memcpy(dstval, (void*) (dest + misoffset), 64);
216 * dstval[63]='\0';
217 * T_LOG("*dest %s\n", dstval);*/
218 }
219
220 message->header.msgh_local_port = MACH_PORT_NULL;
221
222 ret = mach_msg(&message->header, MACH_SEND_MSG, message->header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
223 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "CLIENT: mach_msg_send FAILED");
224 } else {
225 T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "CLIENT: mach_msg_rcv FAILED");
226 }
227 }
228}
229
230void
231mach_server_make_memory_entry(mach_port_t replyPort)
232{
233 mach_vm_address_t src = 0, lsrc = 0;
234 mach_vm_size_t size = TESTSZ;
235 memory_object_size_t memsz = 0;
236 kern_return_t kr;
237 boolean_t modified_in_server = FALSE, perm_changed = FALSE;
238 ipc_message_t message;
239 ipc_message_t *reply = NULL;
240 char src_val[64], dst_val[64];
241 mach_msg_size_t replySize = 0;
242 void *buffer = NULL;
243 int flags = 0;
244 mach_port_t memport = 0;
245 int mementry_pass_idx = 0;
246 mach_vm_offset_t misoffset = 0;
247
248 if (debug) {
249 T_LOG("\n*************** make_memory_entry_test START ***************\n");
250 }
251
252 if (mach_server_data_setup(&buffer) != 0) {
253 server_error_out(replyPort);
254 }
255
256 if (buffer == NULL) {
257 mach_server_data_cleanup(NULL, 0, 0);
258 exit(0);
259 }
260
261 replySize = sizeof(ipc_message_t) + sizeof(mach_msg_trailer_t) + 64;
262 reply = calloc(1, replySize);
263
264test_different_mementry_mode:
265 /* create message to send over rights/address/pid/size */
266 mach_server_construct_header(&message, replyPort);
267
268 /* allocation that we plan to remap in the client */
269 mach_server_create_allocation(&src, size, buffer);
270
271 memsz = 8191;
272 lsrc = src + 94095;
273 int pgmask = (getpagesize() - 1);
274 misoffset = 94095 - (94095 & ~pgmask);
275
276 if (mementry_pass_idx < 2) {
277 if (mementry_pass_idx == 0) {
278 flags = VM_PROT_DEFAULT | MAP_MEM_VM_COPY | MAP_MEM_USE_DATA_ADDR;
279 T_LOG("mach_make_memory_entry VM_COPY | USE_DATA_ADDR test...");
280 } else {
281 flags = VM_PROT_READ | MAP_MEM_VM_SHARE;
282 T_LOG("mach_make_memory_entry VM_SHARE test...");
283 }
284 kr = mach_vm_protect(mach_task_self(), (mach_vm_address_t) lsrc, (mach_vm_size_t)getpagesize(), FALSE, VM_PROT_READ);
285 assert(kr == KERN_SUCCESS);
286 perm_changed = TRUE;
287 } else {
288 flags = VM_PROT_DEFAULT;
289 perm_changed = FALSE;
290 T_LOG("mach_make_memory_entry DEFAULT test...");
291 }
292
293 kr = mach_make_memory_entry_64(mach_task_self(), &memsz, lsrc, flags, &memport, MACH_PORT_NULL);
294 if (kr != KERN_SUCCESS) {
295 T_LOG("ERROR: mach_make_memory_entry_64 try (%d) failed in Client: (%d) %s\n",
296 mementry_pass_idx + 1, kr, mach_error_string(kr));
297 server_error_out(replyPort);
298 }
299
300 mach_server_contruct_payload(&message, lsrc, memport, memsz, misoffset, ((flags & MAP_MEM_VM_COPY) == MAP_MEM_VM_COPY) /*copy*/, VM_OP_MEMENTRY);
301
302 memcpy(src_val, (void*) lsrc, 64);
303 src_val[63] = '\0';
304
305check_again:
306 /* Sending over pid/src address/size */
307 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
308
309 if (kr != KERN_SUCCESS) {
310 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
311 server_error_out(replyPort);
312 }
313
314 /* Ack from client that it worked */
315
316 bzero(reply, replySize);
317
318 kr = mach_msg(&reply->header, MACH_RCV_MSG, 0, replySize, replyPort, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
319 if (kr != KERN_SUCCESS) {
320 T_LOG("ERROR: Failed to get reply from client: (%d) %s\n", kr, mach_error_string(kr));
321 server_error_out(replyPort);
322 }
323
324 memcpy(dst_val, &reply->value, 64);
325 dst_val[63] = '\0';
326
327 if (modified_in_server == FALSE) {
328 if (strncmp(src_val, dst_val, 64)) {
329 T_LOG("FAILED\n");
330 T_LOG("(%d) Pre modification mach_make_memory_entry() FAILED: copy(%d) src_val: %s dest_val: %s\n", mementry_pass_idx + 1, message.copy, src_val, dst_val);
331 server_error_out(replyPort);
332 }
333 } else {
334 if (message.copy == TRUE) {
335 if (strncmp(src_val, dst_val, 64) == 0) {
336 T_LOG("FAILED\n");
337 T_LOG("(%d) Data mismatch with Copy: %d src_val: %s dest_val: %s\n",
338 mementry_pass_idx + 1, message.copy, src_val, dst_val);
339 server_error_out(replyPort);
340 }
341 } else {
342 if (strncmp(src_val, dst_val, 64)) {
343 T_LOG("FAILED\n");
344 T_LOG("(%d) Data mismatch with Copy: %d src_val: %s dest_val: %s\n",
345 mementry_pass_idx + 1, message.copy, src_val, dst_val);
346 server_error_out(replyPort);
347 }
348 }
349 }
350
351 if (modified_in_server == FALSE) {
352 /* Now we change our data that has been mapped elsewhere */
353 if (perm_changed) {
354 kr = mach_vm_protect(mach_task_self(), (mach_vm_address_t) lsrc, (mach_vm_size_t)getpagesize(), FALSE, VM_PROT_READ | VM_PROT_WRITE);
355 assert(kr == KERN_SUCCESS);
356 }
357
358 memcpy((void*) lsrc, "THIS IS DIFFERENT -- BUT WE DON'T know if that's expecTED", 64);
359
360 if (perm_changed) {
361 kr = mach_vm_protect(mach_task_self(), (mach_vm_address_t) lsrc, (mach_vm_size_t)getpagesize(), FALSE, VM_PROT_READ);
362 assert(kr == KERN_SUCCESS);
363 }
364
365 memcpy(src_val, (void*) lsrc, 64);
366 src_val[63] = '\0';
367 modified_in_server = TRUE;
368 message.vm_op = VM_OP_NONE;
369
370 /* Check to see if the data in the other process is as expected */
371 goto check_again;
372 }
373
374 if (mementry_pass_idx < 2) {
375 /* Next remap mode...so ask the other process to unmap the older mapping. */
376 message.vm_op = VM_OP_UNMAP;
377 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
378 if (kr != KERN_SUCCESS) {
379 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
380 server_error_out(replyPort);
381 }
382
383 mach_port_deallocate(mach_task_self(), memport);
384 memport = MACH_PORT_NULL;
385 mach_vm_deallocate(mach_task_self(), src, size);
386
387 T_LOG("PASSED\n");
388
389 mementry_pass_idx++;
390 modified_in_server = FALSE;
391
392 goto test_different_mementry_mode;
393 }
394
395 T_LOG("PASSED\n");
396
397 /* Unmap old mapping in the other process. */
398 message.vm_op = VM_OP_UNMAP;
399 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
400 if (kr != KERN_SUCCESS) {
401 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
402 server_error_out(replyPort);
403 }
404
405 free(reply);
406 reply = NULL;
407
408 mach_port_deallocate(mach_task_self(), memport);
409 memport = MACH_PORT_NULL;
410
411 mach_server_data_cleanup(buffer, src, size);
412 buffer = NULL;
413
414 if (debug) {
415 T_LOG("*************** mach_make_memory_entry_test END ***************\n");
416 }
417}
418
419void
420mach_server_read(mach_port_t replyPort, int op)
421{
422 mach_vm_address_t src;
423 mach_vm_size_t size = TESTSZ;
424 kern_return_t kr;
425 boolean_t modified_in_server = FALSE;
426 ipc_message_t message;
427 char src_val[64], dst_val[64];
428 mach_msg_size_t replySize = 0;
429 ipc_message_t *reply = NULL;
430 void *buffer = NULL;
431
432 if (debug) {
433 T_LOG("\n*************** vm_read / write / overwrite_test START ***************\n");
434 }
435
436 {
437 char opname[16];
438 if (op == VM_OP_READ) {
439 strlcpy(opname, "read", 5);
440 }
441 if (op == VM_OP_WRITE) {
442 strlcpy(opname, "write", 6);
443 }
444 if (op == VM_OP_READ_OVERWRITE) {
445 strlcpy(opname, "read_overwrite", 15);
446 }
447
448 T_LOG("vm_%s test...", opname);
449 }
450
451 if (mach_server_data_setup(&buffer) != 0) {
452 server_error_out(replyPort);
453 }
454
455 if (buffer == NULL) {
456 mach_server_data_cleanup(NULL, 0, 0);
457 exit(0);
458 }
459
460 replySize = sizeof(ipc_message_t) + sizeof(mach_msg_trailer_t) + 64;
461 reply = calloc(1, replySize);
462
463 /* create message to send over rights/address/pid/size */
464 mach_server_construct_header(&message, replyPort);
465
466 /* allocation that we plan to remap in the client */
467 mach_server_create_allocation(&src, size, buffer);
468
469 mach_server_contruct_payload(&message, src, MACH_PORT_NULL /* port */, size, 0, TRUE /*copy*/, op);
470 if (debug) {
471 T_LOG("server COPY: Sending 0x%llx, %d, 0x%llx\n", message.address, getpid(), message.size);
472 }
473 memcpy(src_val, (void*)message.address, 64);
474
475check_again:
476 /* Sending over pid/src address/size */
477 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
478 if (kr != KERN_SUCCESS) {
479 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
480 server_error_out(replyPort);
481 }
482
483 /* Ack from client that it worked */
484
485 bzero(reply, replySize);
486
487 kr = mach_msg(&reply->header, MACH_RCV_MSG, 0, replySize, replyPort, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
488 if (kr != KERN_SUCCESS) {
489 T_LOG("ERROR: Failed to get reply from client: (%d) %s\n", kr, mach_error_string(kr));
490 server_error_out(replyPort);
491 }
492
493 memcpy(dst_val, &reply->value, 64);
494
495 if (modified_in_server == FALSE) {
496 if (strncmp(src_val, dst_val, 64)) {
497 T_LOG("Pre modification (op: %d) FAILED: src_val: %s dest_val: %s\n", op, src_val, dst_val);
498 server_error_out(replyPort);
499 }
500 } else {
501 if (strncmp(src_val, dst_val, 64) == 0) {
502 T_LOG("Data mismatch (op:%d) with Copy: %d src_val: %s dest_val: %s\n", op, message.copy, src_val, dst_val);
503 server_error_out(replyPort);
504 }
505 }
506
507 if (modified_in_server == FALSE) {
508 /* Now we change our data that has been mapped elsewhere */
509 memcpy((void*)message.address, "THIS IS DIFFERENT -- BUT WE DON'T know if that's expecTED", 64);
510 memcpy(src_val, (void*)message.address, 64);
511 modified_in_server = TRUE;
512 message.vm_op = VM_OP_NONE;
513
514 /* Check to see if the data in the other process is as expected */
515 goto check_again;
516 }
517
518 /* Unmap old mapping in the other process. */
519 message.vm_op = VM_OP_UNMAP;
520 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
521 if (kr != KERN_SUCCESS) {
522 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
523 server_error_out(replyPort);
524 }
525
526 free(reply);
527 reply = NULL;
528
529 mach_server_data_cleanup(buffer, src, size);
530 buffer = NULL;
531
532 if (debug) {
533 T_LOG("*************** vm_read_test END ***************\n");
534 }
535
536 T_LOG("PASSED\n");
537}
538
539void
540mach_server_remap(mach_port_t replyPort)
541{
542 mach_vm_address_t src = 0, lsrc = 0;
543 mach_vm_size_t size = TESTSZ;
544 kern_return_t kr;
545 int remap_copy_pass_idx = 0;
546 boolean_t modified_in_server = FALSE;
547 void *buffer;
548 ipc_message_t message;
549 char src_val[64], dst_val[64];
550 mach_msg_size_t replySize = 0;
551 ipc_message_t *reply = NULL;
552
553 if (debug) {
554 T_LOG("\n*************** vm_remap_test START ***************\n");
555 }
556
557 if (mach_server_data_setup(&buffer) != 0) {
558 server_error_out(replyPort);
559 }
560
561 if (buffer == NULL) {
562 mach_server_data_cleanup(NULL, 0, 0);
563 exit(0);
564 }
565
566 replySize = sizeof(ipc_message_t) + sizeof(mach_msg_trailer_t) + 64;
567 reply = calloc(1, replySize);
568
569remap_again:
570
571 T_LOG("vm_remap (copy = %s) test...", ((remap_copy_pass_idx == 0) ? "FALSE" : "TRUE"));
572
573 /* create message to send over rights/address/pid/size */
574 mach_server_construct_header(&message, replyPort);
575
576 /* server allocation that we plan to remap in the client */
577 mach_server_create_allocation(&src, size, buffer);
578
579 lsrc = src + 8193;
580
581 mach_server_contruct_payload(&message, lsrc, MACH_PORT_NULL /* port */, size - 9000, 0, remap_copy_pass_idx /*copy*/, VM_OP_REMAP);
582 if (debug) {
583 T_LOG("server COPY: Sending 0x%llx, %d, 0x%llx\n", message.address, getpid(), message.size);
584 }
585
586 memcpy(src_val, (void*)lsrc, 64);
587 src_val[63] = '\0';
588
589check_again:
590 /* Sending over pid/src address/size */
591 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
592 if (kr != KERN_SUCCESS) {
593 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
594 server_error_out(replyPort);
595 }
596
597 /* Ack from client that it worked */
598
599 bzero(reply, replySize);
600
601 kr = mach_msg(&reply->header, MACH_RCV_MSG, 0, replySize, replyPort, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
602 if (kr != KERN_SUCCESS) {
603 T_LOG("ERROR: Failed to get reply from client: (%d) %s\n", kr, mach_error_string(kr));
604 server_error_out(replyPort);
605 }
606
607 memcpy(dst_val, &reply->value, 64);
608 dst_val[63] = '\0';
609
610
611 if (modified_in_server == FALSE) {
612 if (strncmp(src_val, dst_val, 64)) {
613 T_LOG("Pre modification remap() FAILED: copy(%d) src_val: %s dest_val: %s\n",
614 message.copy, src_val, dst_val);
615 server_error_out(replyPort);
616 }
617 } else {
618 if (message.copy == TRUE) {
619 if (strcmp(src_val, dst_val) == 0) {
620 T_LOG("Data mismatch with Copy: %d src_val: %s dest_val: %s\n",
621 message.copy, src_val, dst_val);
622 server_error_out(replyPort);
623 }
624 } else {
625 if (strcmp(src_val, dst_val)) {
626 T_LOG("Data mismatch with Copy: %d src_val: %s dest_val: %s\n",
627 message.copy, src_val, dst_val);
628 server_error_out(replyPort);
629 }
630 }
631 }
632
633 if (modified_in_server == FALSE) {
634 /* Now we change our data that has been mapped elsewhere */
635 memcpy((void*)message.address, "THIS IS DIFFERENT -- BUT WE DON'T know if that's expecTED", 64);
636 memcpy(src_val, (void*)message.address, 64);
637 src_val[63] = '\0';
638
639 modified_in_server = TRUE;
640 message.vm_op = VM_OP_NONE;
641
642 /* Check to see if the data in the other process is as expected */
643 goto check_again;
644 }
645
646 if (remap_copy_pass_idx == 0) {
647 /* Next remap mode...so ask the other process to unmap the older mapping. */
648 message.vm_op = VM_OP_UNMAP;
649 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
650 if (kr != KERN_SUCCESS) {
651 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
652 server_error_out(replyPort);
653 }
654
655 mach_vm_deallocate(mach_task_self(), src, size);
656
657 T_LOG("PASSED\n");
658
659 remap_copy_pass_idx++;
660 modified_in_server = FALSE;
661
662 /* Next remap pass to test (copy == TRUE). Send data out again to the other process to remap. */
663 goto remap_again;
664 }
665
666 T_LOG("PASSED\n");
667
668 /* Unmap old mapping in the other process. */
669 message.vm_op = VM_OP_UNMAP;
670 kr = mach_msg(&message.header, MACH_SEND_MSG, message.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
671 if (kr != KERN_SUCCESS) {
672 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", kr, mach_error_string(kr));
673 server_error_out(replyPort);
674 }
675
676 free(reply);
677 reply = NULL;
678
679 mach_server_data_cleanup(buffer, src, size);
680 buffer = NULL;
681
682 if (debug) {
683 T_LOG("*************** vm_remap_test END ***************\n");
684 }
685}