this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Create a udev rule to set /dev/mach to 0666 And update daring.c to print the path of the module was loaded

+151 -141
+4
CMakeLists.txt
··· 100 100 install(CODE "execute_process(COMMAND bash ${DARLING_TOP_DIRECTORY}/src/setup-ld-so.sh WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/libexec/darling)") 101 101 InstallSymlink(/Volumes/SystemRoot/lib ${CMAKE_INSTALL_PREFIX}/libexec/darling/lib) 102 102 InstallSymlink(/Volumes/SystemRoot/lib64 ${CMAKE_INSTALL_PREFIX}/libexec/darling/lib64) 103 + 104 + # Our udev rules, so /dev/mach has 0666 permissions 105 + install(DIRECTORY etc/udev DESTINATION /etc) 106 + 103 107 endif (NOT DARLING_NO_EXECUTABLES)
+2
etc/udev/rules.d/00-darling-mach.rules
··· 1 + # Make /dev/mach accessible by all users 2 + KERNEL=="mach", NAME="mach", MODE="0666"
+5 -1
src/dyld/darling.c
··· 829 829 path = miscpath; 830 830 } 831 831 832 - fd = open(path, O_RDONLY|O_CLOEXEC); 832 + fd = open(path, O_RDONLY); 833 833 if (fd < 0) 834 834 { 835 835 fprintf(stderr, "Cannot open kernel module\n"); ··· 842 842 return 1; 843 843 } 844 844 845 + printf("Loaded kernel module: %s\n", path); 846 + 847 + close(fd); 848 + 845 849 return 0; 846 850 } 847 851
+140 -140
src/lkm/traps.c
··· 1 1 /* 2 2 * Darling Mach Linux Kernel Module 3 3 * Copyright (C) 2015 Lubos Dolezel 4 - * 4 + * 5 5 * This program is free software; you can redistribute it and/or 6 6 * modify it under the terms of the GNU General Public License 7 7 * as published by the Free Software Foundation; either version 2 8 8 * of the License, or (at your option) any later version. 9 - * 9 + * 10 10 * This program is distributed in the hope that it will be useful, 11 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 13 * GNU General Public License for more details. 14 - * 14 + * 15 15 * You should have received a copy of the GNU General Public License 16 16 * along with this program; if not, write to the Free Software 17 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ··· 29 29 #include <linux/dcache.h> 30 30 #include <linux/kernel.h> 31 31 #include <linux/mm.h> 32 + #include <linux/syscalls.h> 32 33 #include "darling_task.h" 33 34 #include "traps.h" 34 35 #include "ipc_space.h" ··· 101 102 { 102 103 // mach_port_name_t name; 103 104 int err; 104 - 105 + 105 106 err = misc_register(&mach_dev); 106 107 if (err < 0) 107 108 goto fail; 108 - 109 + 109 110 darling_task_init(); 110 111 setup_proc_entry(); 111 112 ipc_space_init(&kernel_namespace); ··· 139 140 darling_mach_port_t* task_port; 140 141 darling_mach_port_t* thread_port; 141 142 mach_task_t* task; 142 - 143 + 143 144 if (ipc_port_new(&task_port) != KERN_SUCCESS) 144 145 return -ENOMEM; 145 - 146 + 146 147 if (ipc_port_new(&thread_port) != KERN_SUCCESS) 147 148 { 148 149 ipc_port_put(task_port); 149 150 return -ENOMEM; 150 151 } 151 - 152 + 152 153 task = ipc_port_make_task(task_port, current->pid); 153 154 file->private_data = task_port; 154 - 155 + 155 156 ipc_port_make_thread(thread_port); 156 - 157 + 157 158 darling_task_set_current(ipc_port_get_task(task_port)); 158 159 darling_task_register_thread(task, thread_port); 159 160 ··· 163 164 int mach_dev_release(struct inode* ino, struct file* file) 164 165 { 165 166 darling_mach_port_t* task_port; 166 - 167 + 167 168 task_port = (darling_mach_port_t*) file->private_data; 168 169 ipc_port_put(task_port); 169 - 170 + 170 171 darling_task_set_current(NULL); 171 - 172 + 172 173 return 0; 173 174 } 174 175 175 176 long mach_dev_ioctl(struct file* file, unsigned int ioctl_num, unsigned long ioctl_paramv) 176 177 { 177 178 const unsigned int num_traps = sizeof(mach_traps) / sizeof(mach_traps[0]); 178 - 179 + 179 180 darling_mach_port_t* task_port = (darling_mach_port_t*) file->private_data; 180 181 mach_task_t* task; 181 - 182 + 182 183 debug_msg("function 0x%x called...\n", ioctl_num); 183 - 184 + 184 185 ioctl_num -= DARLING_MACH_API_BASE; 185 - 186 + 186 187 if (ioctl_num >= num_traps) 187 188 return -ENOSYS; 188 189 189 190 if (!mach_traps[ioctl_num]) 190 191 return -ENOSYS; 191 - 192 + 192 193 task = ipc_port_get_task(task_port); 193 - 194 + 194 195 return mach_traps[ioctl_num](task, ioctl_paramv); 195 196 } 196 197 ··· 204 205 mach_msg_return_t ret; 205 206 mach_port_name_t name; 206 207 darling_mach_port_t* port; 207 - 208 + 208 209 ret = ipc_port_new(&port); 209 210 if (ret != KERN_SUCCESS) 210 211 return 0; 211 - 212 + 212 213 ret = ipc_space_make_receive(&task->namespace, port, &name); 213 214 if (ret != KERN_SUCCESS) 214 215 { 215 216 ipc_port_put(port); 216 217 return 0; 217 218 } 218 - 219 + 219 220 return name; 220 221 } 221 222 ··· 223 224 { 224 225 struct mach_port_right* right; 225 226 mach_task_t* task; 226 - 227 + 227 228 right = ipc_space_lookup(&task_self->namespace, name); 228 229 if (right == NULL) 229 230 return NULL; 230 - 231 + 231 232 // NOTE: If XNU were to support accessing other tasks, 232 233 // we would need to safely add a reference to the task at this point. 233 234 task = ipc_port_get_task(right->port); 234 - 235 + 235 236 ipc_port_unlock(right->port); 236 - 237 + 237 238 return task; 238 239 } 239 240 ··· 243 244 struct mach_port_mod_refs_args args; 244 245 struct mach_port_right* right = NULL; 245 246 kern_return_t ret; 246 - 247 + 247 248 if (copy_from_user(&args, in_args, sizeof(args))) 248 249 return KERN_INVALID_ADDRESS; 249 - 250 + 250 251 ipc_space_lock(&task_self->namespace); 251 - 252 + 252 253 // We behave like XNU here 253 254 if (port_name_to_task(task_self, args.task_right_name) != task_self) 254 255 { ··· 256 257 ret = MACH_SEND_INVALID_DEST; 257 258 goto err; 258 259 } 259 - 260 + 260 261 right = ipc_space_lookup(&task_self->namespace, args.port_right_name); 261 262 if (right == NULL) 262 263 { ··· 264 265 ret = KERN_INVALID_NAME; 265 266 goto err; 266 267 } 267 - 268 + 268 269 ret = ipc_right_mod_refs(right, args.right_type, args.delta); 269 - 270 + 270 271 if (ipc_right_put_if_noref(right, &task_self->namespace, args.port_right_name)) 271 272 right = NULL; 272 - 273 + 273 274 err: 274 275 if (right != NULL) 275 276 ipc_port_unlock(right->port); 276 - 277 + 277 278 ipc_space_unlock(&task_self->namespace); 278 - 279 + 279 280 return ret; 280 281 } 281 282 ··· 283 284 { 284 285 mach_port_name_t name; 285 286 kern_return_t ret; 286 - 287 + 287 288 ipc_port_lock(task->task_self); 288 - 289 + 289 290 ret = ipc_space_make_send(&task->namespace, task->task_self, false, &name); 290 - 291 + 291 292 ipc_port_unlock(task->task_self); 292 - 293 + 293 294 if (ret == KERN_SUCCESS) 294 295 return name; 295 296 else ··· 301 302 mach_port_name_t name; 302 303 kern_return_t ret; 303 304 darling_mach_port_t* thread_port; 304 - 305 + 305 306 ipc_port_lock(task->task_self); 306 - 307 + 307 308 thread_port = darling_task_lookup_thread(task, current->pid); 308 309 if (thread_port == NULL) 309 310 { ··· 312 313 ipc_port_unlock(task->task_self); 313 314 return KERN_RESOURCE_SHORTAGE; 314 315 } 315 - 316 + 316 317 ipc_port_make_thread(thread_port); 317 318 darling_task_register_thread(task, thread_port); 318 319 } 319 - 320 + 320 321 ipc_port_unlock(task->task_self); 321 - 322 + 322 323 ret = ipc_space_make_send(&task->namespace, thread_port, false, &name); 323 - 324 + 324 325 if (ret == KERN_SUCCESS) 325 326 return name; 326 327 else ··· 331 332 { 332 333 mach_port_name_t name; 333 334 kern_return_t ret; 334 - 335 + 335 336 ipc_port_lock(host_port); 336 - 337 + 337 338 ret = ipc_space_make_send(&task->namespace, host_port, false, &name); 338 - 339 + 339 340 ipc_port_unlock(host_port); 340 - 341 + 341 342 if (ret == KERN_SUCCESS) 342 343 return name; 343 344 else ··· 350 351 struct mach_port_allocate_args args; 351 352 darling_mach_port_t* port; 352 353 kern_return_t ret = KERN_SUCCESS; 353 - 354 + 354 355 if (copy_from_user(&args, in_out_args, sizeof(args))) 355 356 return KERN_INVALID_ADDRESS; 356 - 357 + 357 358 ipc_space_lock(&task->namespace); 358 - 359 + 359 360 if (port_name_to_task(task, args.task_right_name) != task) 360 361 { 361 362 debug_msg("_kernelrpc_mach_port_allocate_trap() -> MACH_SEND_INVALID_DEST\n"); 362 - 363 + 363 364 ipc_space_unlock(&task->namespace); 364 365 ret = MACH_SEND_INVALID_DEST; 365 366 goto err; 366 367 } 367 - 368 + 368 369 ipc_space_unlock(&task->namespace); 369 - 370 + 370 371 switch (args.right_type) 371 372 { 372 373 case MACH_PORT_RIGHT_RECEIVE: ··· 374 375 ret = ipc_port_new(&port); 375 376 if (ret != KERN_SUCCESS) 376 377 return ret; 377 - 378 + 378 379 break; 379 380 } 380 381 case MACH_PORT_RIGHT_DEAD_NAME: ··· 388 389 ret = ipc_port_set_new(&port); 389 390 if (ret != KERN_SUCCESS) 390 391 return ret; 391 - 392 + 392 393 break; 393 394 } 394 395 default: ··· 396 397 return KERN_INVALID_VALUE; 397 398 } 398 399 } 399 - 400 + 400 401 ret = ipc_space_make_receive(&task->namespace, port, 401 402 &args.out_right_name); 402 403 if (ret != KERN_SUCCESS) ··· 404 405 ipc_port_put(port); 405 406 goto err; 406 407 } 407 - 408 + 408 409 if (copy_to_user(in_out_args, &args, sizeof(args))) 409 410 { 410 411 ipc_port_put(port); 411 412 ret = KERN_PROTECTION_FAILURE; 412 413 goto err; 413 414 } 414 - 415 + 415 416 err: 416 417 return ret; 417 418 } ··· 422 423 struct mach_port_deallocate_args args; 423 424 struct mach_port_right* right = NULL; 424 425 kern_return_t ret = KERN_SUCCESS; 425 - 426 + 426 427 if (copy_from_user(&args, in_args, sizeof(args))) 427 428 return KERN_INVALID_ADDRESS; 428 - 429 + 429 430 ipc_space_lock(&task->namespace); 430 - 431 + 431 432 if (port_name_to_task(task, args.task_right_name) != task) 432 433 { 433 434 debug_msg("_kernelrpc_mach_port_deallocate_trap() -> MACH_SEND_INVALID_DEST\n"); 434 - 435 + 435 436 ret = MACH_SEND_INVALID_DEST; 436 437 goto err; 437 438 } 438 - 439 + 439 440 right = ipc_space_lookup(&task->namespace, args.port_right_name); 440 441 if (right == NULL || right->type == MACH_PORT_RIGHT_RECEIVE) 441 442 { 442 443 debug_msg("_kernelrpc_mach_port_deallocate_trap() -> KERN_INVALID_RIGHT\n"); 443 - 444 + 444 445 ret = KERN_INVALID_RIGHT; 445 446 goto err; 446 447 } 447 - 448 + 448 449 if (right->port != NULL) 449 450 { 450 451 ipc_right_mod_refs(right, right->type, -1); 451 - 452 + 452 453 if (ipc_right_put_if_noref(right, &task->namespace, args.port_right_name)) 453 454 right = NULL; 454 455 } 455 - 456 + 456 457 err: 457 458 if (right != NULL) 458 459 ipc_port_unlock(right->port); ··· 465 466 struct mach_port_destroy_args* in_args) 466 467 { 467 468 struct mach_port_destroy_args args; 468 - 469 + 469 470 if (copy_from_user(&args, in_args, sizeof(args))) 470 471 return KERN_INVALID_ADDRESS; 471 - 472 + 472 473 return _kernelrpc_mach_port_destroy(task, args.task_right_name, 473 474 args.port_right_name); 474 475 } ··· 477 478 mach_port_name_t task_name, mach_port_name_t right_name) 478 479 { 479 480 kern_return_t ret = KERN_SUCCESS; 480 - 481 + 481 482 ipc_space_lock(&task->namespace); 482 - 483 + 483 484 if (port_name_to_task(task, task_name) != task) 484 485 { 485 486 debug_msg("_kernelrpc_mach_port_destroy_trap() -> MACH_SEND_INVALID_DEST\n"); 486 - 487 + 487 488 ret = MACH_SEND_INVALID_DEST; 488 489 goto err; 489 490 } 490 - 491 + 491 492 ret = ipc_space_right_put(&task->namespace, right_name); 492 - 493 + 493 494 err: 494 495 495 496 ipc_space_unlock(&task->namespace); ··· 501 502 { 502 503 struct mach_msg_overwrite_args args; 503 504 kern_return_t ret = MACH_MSG_SUCCESS; 504 - 505 + 505 506 debug_msg("mach_msg_overwrite_trap()"); 506 - 507 + 507 508 if (copy_from_user(&args, in_args, sizeof(args))) 508 509 { 509 510 debug_msg("!!! Cannot copy %d bytes from %p\n", 510 511 sizeof(args), in_args); 511 512 return KERN_INVALID_ADDRESS; 512 513 } 513 - 514 + 514 515 if (args.option & MACH_SEND_MSG) 515 516 { 516 517 mach_msg_header_t* msg; 517 - 518 + 518 519 if (args.send_size > 10*4096) 519 520 { 520 521 debug_msg("\t-> MACH_SEND_NO_BUFFER\n"); ··· 525 526 debug_msg("\t-> MACH_SEND_MSG_TOO_SMALL\n"); 526 527 return MACH_SEND_MSG_TOO_SMALL; 527 528 } 528 - 529 + 529 530 msg = (mach_msg_header_t*) kmalloc(args.send_size, GFP_KERNEL); 530 531 if (msg == NULL) 531 532 return MACH_SEND_NO_BUFFER; 532 - 533 + 533 534 if (copy_from_user(msg, args.msg, args.send_size)) 534 535 { 535 536 debug_msg("!!! Cannot copy %d bytes from %p\n", ··· 537 538 kfree(msg); 538 539 return KERN_INVALID_ADDRESS; 539 540 } 540 - 541 + 541 542 msg->msgh_size = args.send_size; 542 543 msg->msgh_bits &= MACH_MSGH_BITS_USER; 543 - 544 + 544 545 ret = ipc_msg_send(&task->namespace, msg, 545 546 (args.option & MACH_SEND_TIMEOUT) ? args.timeout : MACH_MSG_TIMEOUT_NONE, 546 547 args.option); 547 - 548 + 548 549 if (ret != MACH_MSG_SUCCESS) 549 550 return ret; 550 551 } 551 - 552 + 552 553 if (args.option & MACH_RCV_MSG) 553 554 { 554 555 ret = ipc_msg_recv(task, args.rcv_name, args.rcv_msg, args.recv_size, ··· 569 570 { 570 571 struct semaphore_signal_args args; 571 572 darling_mach_port_right_t* right; 572 - 573 + 573 574 if (copy_from_user(&args, in_args, sizeof(args))) 574 575 return KERN_INVALID_ADDRESS; 575 - 576 + 576 577 ipc_space_lock(&task->namespace); 577 - 578 + 578 579 right = ipc_space_lookup(&task->namespace, args.signal); 579 - 580 + 580 581 ipc_space_unlock(&task->namespace); 581 - 582 + 582 583 if (right == NULL || !PORT_IS_VALID(right->port)) 583 584 { 584 585 if (right != NULL) 585 586 ipc_port_unlock(right->port); 586 587 return KERN_INVALID_ARGUMENT; 587 588 } 588 - 589 + 589 590 return mach_semaphore_signal(right->port); 590 591 } 591 592 ··· 594 595 { 595 596 struct semaphore_signal_all_args args; 596 597 darling_mach_port_right_t* right; 597 - 598 + 598 599 if (copy_from_user(&args, in_args, sizeof(args))) 599 600 return KERN_INVALID_ADDRESS; 600 - 601 + 601 602 ipc_space_lock(&task->namespace); 602 - 603 + 603 604 right = ipc_space_lookup(&task->namespace, args.signal); 604 - 605 + 605 606 ipc_space_unlock(&task->namespace); 606 - 607 + 607 608 if (right == NULL || !PORT_IS_VALID(right->port)) 608 609 { 609 610 if (right != NULL) 610 611 ipc_port_unlock(right->port); 611 612 return KERN_INVALID_ARGUMENT; 612 613 } 613 - 614 + 614 615 return mach_semaphore_signal_all(right->port); 615 616 } 616 617 ··· 619 620 { 620 621 struct semaphore_wait_args args; 621 622 darling_mach_port_right_t* right; 622 - 623 + 623 624 if (copy_from_user(&args, in_args, sizeof(args))) 624 625 return KERN_INVALID_ADDRESS; 625 - 626 + 626 627 ipc_space_lock(&task->namespace); 627 - 628 + 628 629 right = ipc_space_lookup(&task->namespace, args.signal); 629 - 630 + 630 631 ipc_space_unlock(&task->namespace); 631 - 632 + 632 633 if (right == NULL || !PORT_IS_VALID(right->port)) 633 634 { 634 635 if (right != NULL) 635 636 ipc_port_unlock(right->port); 636 637 return KERN_INVALID_ARGUMENT; 637 638 } 638 - 639 + 639 640 return mach_semaphore_wait(right->port); 640 641 } 641 642 ··· 645 646 struct semaphore_wait_signal_args args; 646 647 darling_mach_port_right_t *right_wait, *right_signal; 647 648 kern_return_t ret = KERN_SUCCESS; 648 - 649 + 649 650 if (copy_from_user(&args, in_args, sizeof(args))) 650 651 return KERN_INVALID_ADDRESS; 651 - 652 + 652 653 ipc_space_lock(&task->namespace); 653 - 654 + 654 655 right_signal = ipc_space_lookup(&task->namespace, args.signal); 655 656 if (right_signal == NULL) 656 657 { 657 658 ipc_space_unlock(&task->namespace); 658 659 return KERN_INVALID_ARGUMENT; 659 660 } 660 - 661 + 661 662 if (args.wait != 0) 662 663 right_wait = ipc_space_lookup(&task->namespace, args.wait); 663 664 else 664 665 right_wait = NULL; 665 - 666 + 666 667 ipc_space_unlock(&task->namespace); 667 - 668 + 668 669 if (right_wait != NULL) 669 670 ret = mach_semaphore_wait(right_wait->port); 670 - 671 + 671 672 mach_semaphore_signal(right_signal->port); 672 - 673 + 673 674 return ret; 674 675 } 675 676 ··· 678 679 { 679 680 struct semaphore_timedwait_args args; 680 681 darling_mach_port_right_t* right; 681 - 682 + 682 683 if (copy_from_user(&args, in_args, sizeof(args))) 683 684 return KERN_INVALID_ADDRESS; 684 - 685 + 685 686 ipc_space_lock(&task->namespace); 686 - 687 + 687 688 right = ipc_space_lookup(&task->namespace, args.wait); 688 - 689 + 689 690 ipc_space_unlock(&task->namespace); 690 - 691 + 691 692 if (right == NULL || !PORT_IS_VALID(right->port)) 692 693 { 693 694 if (right != NULL) 694 695 ipc_port_unlock(right->port); 695 696 return KERN_INVALID_ARGUMENT; 696 697 } 697 - 698 + 698 699 return mach_semaphore_timedwait(right->port, args.sec, args.nsec); 699 700 } 700 701 ··· 704 705 struct semaphore_timedwait_signal_args args; 705 706 darling_mach_port_right_t *right_wait, *right_signal; 706 707 kern_return_t ret = KERN_SUCCESS; 707 - 708 + 708 709 if (copy_from_user(&args, in_args, sizeof(args))) 709 710 return KERN_INVALID_ADDRESS; 710 - 711 + 711 712 // debug_msg("semaphore_timedwait_signal_trap: sec=%d, nsec=%d\n", args.sec, 712 713 // args.nsec); 713 - 714 + 714 715 ipc_space_lock(&task->namespace); 715 - 716 + 716 717 right_signal = ipc_space_lookup(&task->namespace, args.signal); 717 718 if (right_signal == NULL) 718 719 { 719 720 ipc_space_unlock(&task->namespace); 720 721 return KERN_INVALID_ARGUMENT; 721 722 } 722 - 723 + 723 724 if (args.wait != 0) 724 725 right_wait = ipc_space_lookup(&task->namespace, args.wait); 725 726 else 726 727 right_wait = NULL; 727 - 728 + 728 729 ipc_space_unlock(&task->namespace); 729 - 730 + 730 731 if (right_wait != NULL) 731 732 ret = mach_semaphore_timedwait(right_wait->port, args.sec, args.nsec); 732 - 733 + 733 734 mach_semaphore_signal(right_signal->port); 734 - 735 + 735 736 return ret; 736 737 } 737 738 ··· 742 743 char name[60]; 743 744 long retval = 0; 744 745 int handled; 745 - 746 + 746 747 if (copy_from_user(&args, in_args, sizeof(args))) 747 748 return -EFAULT; 748 - 749 + 749 750 f = fget(args.fd); 750 751 if (f == NULL) 751 752 return -EBADF; 752 - 753 + 753 754 if (f->f_op->unlocked_ioctl == NULL) 754 755 { 755 756 fput(f); 756 757 return -ENOTTY; 757 758 } 758 - 759 + 759 760 if (d_path(&f->f_path, name, sizeof(name)) == NULL) 760 761 { 761 762 fput(f); 762 763 return -EBADF; 763 764 } 764 - 765 + 765 766 // Perform ioctl translation based on name 766 767 if (strncmp(name, "socket:", 7) == 0) 767 768 handled = bsd_ioctl_xlate_socket(f, &args, &retval); ··· 771 772 handled = bsd_ioctl_xlate_pts(f, &args, &retval); 772 773 else 773 774 handled = bsd_ioctl_xlate_generic(f, &args, &retval); 774 - 775 + 775 776 if (!handled) 776 777 retval = f->f_op->unlocked_ioctl(f, args.request, args.arg); 777 - 778 + 778 779 fput(f); 779 - 780 + 780 781 return retval; 781 782 } 782 783 ··· 789 790 790 791 if (copy_from_user(&args, in_args, sizeof(args))) 791 792 return KERN_INVALID_ADDRESS; 792 - 793 + 793 794 debug_msg("bsdthread_terminate_trap(), pid=%d\n", 794 795 current->pid); 795 796 ipc_space_lock(&task->namespace); 796 - 797 + 797 798 sem = ipc_space_lookup(&task->namespace, args.signal); 798 - 799 + 799 800 ipc_space_unlock(&task->namespace); 800 - 801 + 801 802 // Signal threads calling pthread_join() 802 803 if (PORT_IS_VALID(sem->port)) 803 804 mach_semaphore_signal(sem->port); ··· 818 819 819 820 module_init(mach_init); 820 821 module_exit(mach_exit); 821 -