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 14 void 15 mach_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 230 void 231 mach_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 264 test_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 305 check_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 419 void 420 mach_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 475 check_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 539 void 540 mach_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 569 remap_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 589 check_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 } 686