this repo has no description
1
fork

Configure Feed

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

Merge remote-tracking branch 'origin/mach-portset' into using-machos-experiment

+411 -47
+19 -7
src/kernel/mach_server/client/mach_traps.c
··· 352 352 .delta = delta 353 353 }; 354 354 355 - return ioctl(driver_fd, NR__kernelrpc_mach_port_mod_refs, &args);; 355 + return ioctl(driver_fd, NR__kernelrpc_mach_port_mod_refs, &args); 356 356 } 357 357 358 358 kern_return_t _kernelrpc_mach_port_move_member_trap( ··· 361 361 mach_port_name_t after 362 362 ) 363 363 { 364 - UNIMPLEMENTED_TRAP(); 365 - return KERN_FAILURE; 364 + struct mach_port_move_member_args args = { 365 + .task_right_name = target, 366 + .port_right_name = member, 367 + .pset_right_name = after 368 + }; 369 + return ioctl(driver_fd, NR__kernelrpc_mach_port_move_member_trap, &args); 366 370 } 367 371 368 372 kern_return_t _kernelrpc_mach_port_insert_right_trap( ··· 382 386 mach_port_name_t pset 383 387 ) 384 388 { 385 - UNIMPLEMENTED_TRAP(); 386 - return KERN_FAILURE; 389 + struct mach_port_insert_member_args args = { 390 + .task_right_name = target, 391 + .port_right_name = name, 392 + .pset_right_name = pset 393 + }; 394 + return ioctl(driver_fd, NR__kernelrpc_mach_port_insert_member_trap, &args); 387 395 } 388 396 389 397 kern_return_t _kernelrpc_mach_port_extract_member_trap( ··· 392 400 mach_port_name_t pset 393 401 ) 394 402 { 395 - UNIMPLEMENTED_TRAP(); 396 - return KERN_FAILURE; 403 + struct mach_port_extract_member_args args = { 404 + .task_right_name = target, 405 + .port_right_name = name, 406 + .pset_right_name = pset 407 + }; 408 + return ioctl(driver_fd, NR__kernelrpc_mach_port_extract_member_trap, &args); 397 409 } 398 410 399 411 kern_return_t _kernelrpc_mach_port_construct_trap(
+24
src/lkm/api.h
··· 59 59 NR_mk_timer_arm_trap, 60 60 NR_mk_timer_cancel_trap, 61 61 NR_mk_timer_destroy_trap, 62 + NR__kernelrpc_mach_port_move_member_trap, 63 + NR__kernelrpc_mach_port_insert_member_trap, 64 + NR__kernelrpc_mach_port_extract_member_trap, 62 65 }; 63 66 64 67 struct mach_port_mod_refs_args ··· 109 112 { 110 113 unsigned int task_right_name; 111 114 unsigned int port_right_name; 115 + }; 116 + 117 + struct mach_port_move_member_args 118 + { 119 + unsigned int task_right_name; 120 + unsigned int port_right_name; 121 + unsigned int pset_right_name; 122 + }; 123 + 124 + struct mach_port_insert_member_args 125 + { 126 + unsigned int task_right_name; 127 + unsigned int port_right_name; 128 + unsigned int pset_right_name; 129 + }; 130 + 131 + struct mach_port_extract_member_args 132 + { 133 + unsigned int task_right_name; 134 + unsigned int port_right_name; 135 + unsigned int pset_right_name; 112 136 }; 113 137 114 138 struct semaphore_signal_args
+35 -16
src/lkm/ipc_msg.c
··· 429 429 mach_msg_return_t ret = MACH_MSG_SUCCESS; 430 430 struct ipc_delivered_msg* delivery = NULL; 431 431 darling_mach_port_t* port; 432 + bool was_in_set; 432 433 433 434 debug_msg("ipc_msg_deliver()\n"); 434 435 ··· 448 449 INIT_LIST_HEAD(&delivery->list); 449 450 memcpy(&delivery->kmsg, kmsg, sizeof(*kmsg)); 450 451 delivery->delivered = false; 452 + delivery->recipient_died = false; 451 453 delivery->recipient_freed = kmsg->target->type == MACH_PORT_RIGHT_SEND_ONCE; 452 454 453 455 list_add(&delivery->list, &port->messages); ··· 456 458 debug_msg("-> msg enqueued (%d b), waking up queue %p, queue size %d\n", kmsg->msg->msgh_size, &port->queue_recv, port->queue_size); 457 459 458 460 // Wake up waiting receivers 459 - wake_up(&port->queue_recv); 461 + was_in_set = !hash_empty(port->sets); 462 + if (was_in_set) 463 + { 464 + struct darling_mach_port_le* item; 465 + int bkt; 466 + 467 + hash_for_each(port->sets, bkt, item, node) 468 + { 469 + wake_up_interruptible(&item->port->queue_recv); 470 + } 471 + } 472 + else 473 + wake_up(&port->queue_recv); 460 474 461 475 // Wait (unless target is send once) 462 476 if (kmsg->target->type != MACH_PORT_RIGHT_SEND_ONCE) ··· 467 481 468 482 ipc_port_unlock(port); 469 483 470 - if (timeout) 484 + // TODO: handle cases when port has died 485 + if (timeout > 0) 471 486 { 472 487 if (options & MACH_SEND_INTERRUPT) 473 488 { 474 489 err = wait_event_interruptible_timeout(port->queue_send, 475 - delivery->delivered, msecs_to_jiffies(timeout)); 490 + delivery->delivered || delivery->recipient_died, 491 + msecs_to_jiffies(timeout)); 476 492 } 477 493 else 478 494 { 479 495 err = wait_event_timeout(port->queue_send, 480 - delivery->delivered, msecs_to_jiffies(timeout)); 496 + delivery->delivered || delivery->recipient_died, 497 + msecs_to_jiffies(timeout)); 481 498 } 482 499 } 483 500 else ··· 485 502 if (options & MACH_SEND_INTERRUPT) 486 503 { 487 504 err = wait_event_interruptible(port->queue_send, 488 - delivery->delivered); 505 + delivery->delivered || delivery->recipient_died); 506 + if (err == 0) 507 + err = 1; 489 508 } 490 509 else 491 510 { 492 - err = wait_event_killable(port->queue_send, delivery->delivered); 511 + err = wait_event_killable(port->queue_send, 512 + delivery->delivered || delivery->recipient_died); 493 513 if (err == 0) 494 514 err = 1; 495 515 } 496 516 } 497 517 if (err == -ERESTARTSYS) 498 518 ret = MACH_SEND_INTERRUPTED; 499 - else if (err == 0) 519 + else if (err == 0 && timeout > 0) 500 520 ret = MACH_RCV_TIMED_OUT; 501 - 502 - debug_msg("\t-> kfree(delivery) #1\n"); 503 - kfree(delivery); 521 + else if (delivery->recipient_died) 522 + ret = MACH_SEND_INVALID_DEST; 504 523 } 505 524 else 506 525 { ··· 515 534 ipc_right_lock_port(kmsg->target); 516 535 517 536 // Port may have died 518 - if (PORT_IS_VALID(kmsg->target->port) && delivery != NULL) 537 + if (PORT_IS_VALID(kmsg->target->port)) 519 538 { 520 539 if (!delivery->delivered) 521 540 { ··· 527 546 } 528 547 else 529 548 { 530 - debug_msg("msg delivered\n"); 531 549 darling_mach_port_t* port; 550 + debug_msg("msg delivered\n"); 532 551 533 552 ipc_right_lock_port(kmsg->target); 534 - 553 + 535 554 port = kmsg->target->port; 536 555 ipc_right_put(kmsg->target); 537 556 ··· 874 893 ipc_space_unlock(&task->namespace); 875 894 goto err; 876 895 } 877 - if (right->type == MACH_PORT_RIGHT_RECEIVE && right->port->set != NULL) 896 + if (right->type == MACH_PORT_RIGHT_RECEIVE && !hash_empty(right->port->sets)) 878 897 { 879 898 ret = MACH_RCV_IN_SET; 880 899 ipc_space_unlock(&task->namespace); ··· 910 929 debug_msg("\t-> going to wait with timeout %d on queue %p (intr: %d)\n", timeout, &right->port->queue_recv, options & MACH_RCV_INTERRUPT); 911 930 912 931 // wait for ipc_msg_deliver() to be called somewhere 913 - if (timeout) 932 + if (timeout > 0) 914 933 { 915 934 if (options & MACH_RCV_INTERRUPT) 916 935 { ··· 948 967 ret = MACH_RCV_INTERRUPTED; 949 968 goto err; 950 969 } 951 - else if (err == 0) 970 + else if (err == 0 && timeout > 0) 952 971 { 953 972 ret = MACH_RCV_TIMED_OUT; 954 973 goto err;
+133 -15
src/lkm/ipc_port.c
··· 22 22 #include <linux/slab.h> 23 23 #include <linux/list.h> 24 24 #include <linux/atomic.h> 25 + #include <linux/sched.h> 25 26 #include "debug.h" 26 27 #include "darling_task.h" 27 28 #include "ipc_right.h" ··· 46 47 port->is_server_port = false; 47 48 port->is_port_set = false; 48 49 port->queue_size = 0; 49 - port->set = NULL; 50 50 51 51 INIT_LIST_HEAD(&port->refs); 52 52 INIT_LIST_HEAD(&port->messages); 53 - INIT_LIST_HEAD(&port->set_head); 53 + hash_init(port->sets); 54 54 init_waitqueue_head(&port->queue_send); 55 55 init_waitqueue_head(&port->queue_recv); 56 56 ··· 78 78 port->is_port_set = true; 79 79 80 80 INIT_LIST_HEAD(&port->refs); 81 - INIT_LIST_HEAD(&port->members); 81 + hash_init(port->members); 82 82 83 83 atomic_inc(&port_count); 84 84 *port_out = port; 85 85 return KERN_SUCCESS; 86 86 } 87 87 88 + static void ipc_portset_delete_member(darling_mach_port_t* pset, darling_mach_port_t* member) 89 + { 90 + struct hlist_node *tmp2; 91 + struct darling_mach_port_le* ref2; 92 + 93 + hash_for_each_possible_safe(pset->members, ref2, tmp2, node, (long)member) 94 + { 95 + if (ref2->port != member) 96 + continue; 97 + hash_del(&ref2->node); 98 + kfree(ref2); 99 + } 100 + } 101 + 102 + static void ipc_port_delete_set(darling_mach_port_t* pset, darling_mach_port_t* member) 103 + { 104 + struct hlist_node *tmp2; 105 + struct darling_mach_port_le* ref2; 106 + 107 + hash_for_each_possible_safe(member->sets, ref2, tmp2, node, (long)pset) 108 + { 109 + if (ref2->port != pset) 110 + continue; 111 + hash_del(&ref2->node); 112 + kfree(ref2); 113 + } 114 + } 115 + 88 116 mach_msg_return_t ipc_port_put(darling_mach_port_t* port) 89 117 { 90 118 struct list_head* p; ··· 97 125 } 98 126 if (port->is_port_set) 99 127 { 128 + int bkt; 129 + struct hlist_node *tmp; 130 + struct darling_mach_port_le* ref; 131 + 100 132 // Iterate referenced ports 101 - list_for_each(p, &port->members) 133 + hash_for_each_safe(port->members, bkt, tmp, ref, node) 102 134 { 103 - darling_mach_port_t* ref; 135 + ipc_port_lock(ref->port); 104 136 105 - ref = list_entry(p, darling_mach_port_t, set_head); 106 - 107 - ipc_port_lock(ref); 108 - ref->set = NULL; 109 - ipc_port_unlock(ref); 137 + // Find ref to self in port's list of sets 138 + ipc_port_delete_set(port, ref->port); 139 + 140 + ipc_port_unlock(ref->port); 141 + 142 + kfree(ref); 110 143 } 111 144 } 112 145 else // ordinary port 113 146 { 114 - if (port->set != NULL) 147 + int bkt; 148 + struct hlist_node *tmp; 149 + struct darling_mach_port_le* ref; 150 + struct ipc_delivered_msg* msg; 151 + 152 + // Remove itself from all port sets we're in 153 + hash_for_each_safe(port->sets, bkt, tmp, ref, node) 115 154 { 116 - list_del(&port->set_head); 117 - port->set = NULL; 155 + ipc_port_lock(ref->port); 156 + 157 + // Find ref to self in port sets's list of ports 158 + ipc_portset_delete_member(ref->port, port); 159 + 160 + ipc_port_unlock(ref->port); 161 + 162 + kfree(ref); 118 163 } 164 + 165 + // set recipient_died to true for all pending msgs 166 + list_for_each_entry(msg, &port->messages, list) 167 + { 168 + msg->recipient_died = true; 169 + } 170 + wake_up_all(&port->queue_send); 171 + wake_up_all(&port->queue_recv); 119 172 } 120 173 121 174 // mark all references as dead ports ··· 134 187 } 135 188 debug_msg("All refs to port %p are now dead\n", port); 136 189 137 - // TODO: Wake up any pending senders etc. 138 - 139 190 atomic_dec(&port_count); 140 191 kfree(port); 192 + return KERN_SUCCESS; 193 + } 194 + 195 + kern_return_t ipc_portset_insert(darling_mach_port_t* pset, darling_mach_port_t* port) 196 + { 197 + struct darling_mach_port_le *pset_member, *port_member; 198 + 199 + if (!pset->is_port_set || port->is_port_set) 200 + return KERN_INVALID_RIGHT; 201 + 202 + pset_member = (struct darling_mach_port_le*) kmalloc(sizeof(*pset_member), GFP_KERNEL); 203 + if (pset_member == NULL) 204 + return KERN_RESOURCE_SHORTAGE; 205 + 206 + port_member = (struct darling_mach_port_le*) kmalloc(sizeof(*pset_member), GFP_KERNEL); 207 + if (port_member == NULL) 208 + { 209 + kfree(pset_member); 210 + return KERN_RESOURCE_SHORTAGE; 211 + } 212 + 213 + pset_member->port = port; 214 + port_member->port = pset; 215 + 216 + hash_add(pset->members, &pset_member->node, (long)port); 217 + hash_add(port->sets, &port_member->node, (long)pset); 218 + 219 + return KERN_SUCCESS; 220 + } 221 + 222 + kern_return_t ipc_portset_move(darling_mach_port_t* pset, darling_mach_port_t* port) 223 + { 224 + int bkt; 225 + struct hlist_node *tmp; 226 + struct darling_mach_port_le* ref; 227 + 228 + if (port->is_port_set) 229 + return KERN_INVALID_RIGHT; 230 + if (pset != NULL && !pset->is_port_set) 231 + return KERN_INVALID_RIGHT; 232 + 233 + // Remove port from all port sets it is in 234 + hash_for_each_safe(port->sets, bkt, tmp, ref, node) 235 + { 236 + // Delete ref on the pset side 237 + ipc_portset_delete_member(pset, port); 238 + 239 + kfree(ref); 240 + } 241 + 242 + // Kill all entries 243 + hash_init(port->sets); 244 + 245 + if (pset != NULL) 246 + return ipc_portset_insert(pset, port); 247 + 248 + return KERN_SUCCESS; 249 + } 250 + 251 + kern_return_t ipc_portset_extract(darling_mach_port_t* pset, darling_mach_port_t* port) 252 + { 253 + if (!pset->is_port_set || port->is_port_set) 254 + return KERN_INVALID_RIGHT; 255 + 256 + ipc_port_delete_set(pset, port); 257 + ipc_portset_delete_member(pset, port); 258 + 141 259 return KERN_SUCCESS; 142 260 } 143 261
+23 -5
src/lkm/ipc_port.h
··· 24 24 #include <linux/mutex.h> 25 25 #include <linux/atomic.h> 26 26 #include <linux/wait.h> 27 + #include <linux/hashtable.h> 27 28 #include "ipc_msg.h" 28 29 29 30 typedef struct server_port server_port_t; ··· 62 63 struct list_head messages; 63 64 unsigned int queue_size; 64 65 wait_queue_head_t queue_send, queue_recv; 65 - darling_mach_port_t* set; 66 - struct list_head set_head; 66 + DECLARE_HASHTABLE(sets, 8); 67 67 }; 68 - 69 - /* Port set vars */ 68 + // Port sets 70 69 struct 71 70 { 72 - struct list_head members; // refers via set_head 71 + DECLARE_HASHTABLE(members, 8); 73 72 }; 74 73 }; 75 74 }; 76 75 76 + // Special type for darling_mach_port list entries 77 + // because ports may be in multiple port sets 78 + struct darling_mach_port_le 79 + { 80 + struct hlist_node node; 81 + struct darling_mach_port* port; 82 + }; 83 + 77 84 struct mach_port_right; 78 85 79 86 struct ipc_delivered_msg ··· 85 92 unsigned char delivered : 1; 86 93 // Set to 1 if this struct is to be deleted by recipient 87 94 unsigned char recipient_freed : 1; 95 + // When set to 1, the receiving port has died and says goodbye 96 + unsigned char recipient_died : 1; 88 97 }; 89 98 90 99 mach_msg_return_t ipc_port_new(darling_mach_port_t** port); 91 100 mach_msg_return_t ipc_port_set_new(darling_mach_port_t** port); 101 + 102 + // in/out: pset and port are locked 103 + kern_return_t ipc_portset_insert(darling_mach_port_t* pset, darling_mach_port_t* port); 104 + 105 + // in/out: pset and port are locked 106 + kern_return_t ipc_portset_extract(darling_mach_port_t* pset, darling_mach_port_t* port); 107 + 108 + // in/out: pset and port are locked, pset may be null 109 + kern_return_t ipc_portset_move(darling_mach_port_t* pset, darling_mach_port_t* port); 92 110 93 111 /** 94 112 * Deallocates the port. Marks all refering rights as PORT_DEAD.
+1 -1
src/lkm/primitives/semaphore.c
··· 251 251 jiffies = nsecs_to_jiffies(((u64) sec) * NSEC_PER_SEC + nsec); 252 252 #endif 253 253 254 - debug_msg("down_timeout(jiffies=%d, pid=%d)\n", jiffies, current->pid); 254 + debug_msg("down_timeout(jiffies=%lu, pid=%d)\n", jiffies, current->pid); 255 255 err = down_timeout_interruptible(&ms->sem, jiffies); 256 256 if (err == -ETIME) 257 257 ret = KERN_OPERATION_TIMED_OUT;
+170 -3
src/lkm/traps.c
··· 90 90 TRAP(NR_mk_timer_arm_trap, mk_timer_arm_trap), 91 91 TRAP(NR_mk_timer_cancel_trap, mk_timer_cancel_trap), 92 92 TRAP(NR_mk_timer_destroy_trap, mk_timer_destroy_trap), 93 + TRAP(NR__kernelrpc_mach_port_move_member_trap, _kernelrpc_mach_port_move_member_trap), 94 + TRAP(NR__kernelrpc_mach_port_insert_member_trap, _kernelrpc_mach_port_insert_member_trap), 95 + TRAP(NR__kernelrpc_mach_port_extract_member_trap, _kernelrpc_mach_port_extract_member_trap), 93 96 }; 94 97 #undef TRAP 95 98 ··· 389 392 port = PORT_DEAD; 390 393 break; 391 394 } 392 - // TODO: missing MACH_PORT_RIGHT_PORT_SET 393 395 case MACH_PORT_RIGHT_PORT_SET: 394 396 { 395 397 ret = ipc_port_set_new(&port); ··· 423 425 return ret; 424 426 } 425 427 428 + kern_return_t _kernelrpc_mach_port_insert_member_trap(mach_task_t* task, 429 + struct mach_port_insert_member_args* in_args) 430 + { 431 + struct mach_port_insert_member_args args; 432 + struct mach_port_right *right_port = NULL; 433 + struct mach_port_right *right_pset = NULL; 434 + kern_return_t ret = KERN_SUCCESS; 435 + 436 + if (copy_from_user(&args, in_args, sizeof(args))) 437 + return KERN_INVALID_ADDRESS; 438 + 439 + if (args.pset_right_name == args.port_right_name) 440 + return KERN_INVALID_RIGHT; 441 + 442 + ipc_space_lock(&task->namespace); 443 + 444 + if (port_name_to_task(task, args.task_right_name) != task) 445 + { 446 + debug_msg("_kernelrpc_mach_port_insert_member_trap() -> MACH_SEND_INVALID_DEST\n"); 447 + 448 + ret = MACH_SEND_INVALID_DEST; 449 + goto err; 450 + } 451 + 452 + right_port = ipc_space_lookup(&task->namespace, args.port_right_name); 453 + if (right_port == NULL || right_port->type != MACH_PORT_RIGHT_RECEIVE) 454 + { 455 + debug_msg("_kernelrpc_mach_port_insert_member_trap() -> KERN_INVALID_RIGHT\n"); 456 + 457 + ret = KERN_INVALID_RIGHT; 458 + goto err; 459 + } 460 + 461 + right_pset = ipc_space_lookup(&task->namespace, args.pset_right_name); 462 + if (right_pset == NULL || right_pset->type != MACH_PORT_RIGHT_RECEIVE) 463 + { 464 + debug_msg("_kernelrpc_mach_port_insert_member_trap() -> KERN_INVALID_RIGHT\n"); 465 + 466 + ret = KERN_INVALID_RIGHT; 467 + goto err; 468 + } 469 + 470 + ret = ipc_portset_insert(right_pset->port, right_port->port); 471 + 472 + err: 473 + if (right_port != NULL) 474 + ipc_port_unlock(right_port->port); 475 + if (right_pset != NULL) 476 + ipc_port_unlock(right_pset->port); 477 + 478 + ipc_space_unlock(&task->namespace); 479 + return ret; 480 + } 481 + 482 + kern_return_t _kernelrpc_mach_port_move_member_trap(mach_task_t* task, 483 + struct mach_port_move_member_args* in_args) 484 + { 485 + struct mach_port_move_member_args args; 486 + struct mach_port_right *right_port = NULL; 487 + struct mach_port_right *right_pset = NULL; 488 + kern_return_t ret = KERN_SUCCESS; 489 + 490 + if (copy_from_user(&args, in_args, sizeof(args))) 491 + return KERN_INVALID_ADDRESS; 492 + 493 + if (args.pset_right_name == args.port_right_name) 494 + return KERN_INVALID_RIGHT; 495 + 496 + ipc_space_lock(&task->namespace); 497 + 498 + if (port_name_to_task(task, args.task_right_name) != task) 499 + { 500 + debug_msg("_kernelrpc_mach_port_move_member_trap() -> MACH_SEND_INVALID_DEST\n"); 501 + 502 + ret = MACH_SEND_INVALID_DEST; 503 + goto err; 504 + } 505 + 506 + right_port = ipc_space_lookup(&task->namespace, args.port_right_name); 507 + if (right_port == NULL || right_port->type != MACH_PORT_RIGHT_RECEIVE) 508 + { 509 + debug_msg("_kernelrpc_mach_port_move_member_trap() -> KERN_INVALID_RIGHT\n"); 510 + 511 + ret = KERN_INVALID_RIGHT; 512 + goto err; 513 + } 514 + 515 + right_pset = ipc_space_lookup(&task->namespace, args.pset_right_name); 516 + if (right_pset == NULL || right_pset->type != MACH_PORT_RIGHT_RECEIVE) 517 + { 518 + debug_msg("_kernelrpc_mach_port_move_member_trap() -> KERN_INVALID_RIGHT\n"); 519 + 520 + ret = KERN_INVALID_RIGHT; 521 + goto err; 522 + } 523 + 524 + ret = ipc_portset_move(right_pset->port, right_port->port); 525 + 526 + err: 527 + if (right_port != NULL) 528 + ipc_port_unlock(right_port->port); 529 + if (right_pset != NULL) 530 + ipc_port_unlock(right_pset->port); 531 + 532 + ipc_space_unlock(&task->namespace); 533 + return ret; 534 + } 535 + 536 + kern_return_t _kernelrpc_mach_port_extract_member_trap(mach_task_t* task, 537 + struct mach_port_extract_member_args* in_args) 538 + { 539 + struct mach_port_extract_member_args args; 540 + struct mach_port_right *right_port = NULL; 541 + struct mach_port_right *right_pset = NULL; 542 + kern_return_t ret = KERN_SUCCESS; 543 + 544 + if (copy_from_user(&args, in_args, sizeof(args))) 545 + return KERN_INVALID_ADDRESS; 546 + 547 + if (args.pset_right_name == args.port_right_name) 548 + return KERN_INVALID_RIGHT; 549 + 550 + ipc_space_lock(&task->namespace); 551 + 552 + if (port_name_to_task(task, args.task_right_name) != task) 553 + { 554 + debug_msg("_kernelrpc_mach_port_move_member_trap() -> MACH_SEND_INVALID_DEST\n"); 555 + 556 + ret = MACH_SEND_INVALID_DEST; 557 + goto err; 558 + } 559 + 560 + right_port = ipc_space_lookup(&task->namespace, args.port_right_name); 561 + if (right_port == NULL || right_port->type != MACH_PORT_RIGHT_RECEIVE) 562 + { 563 + debug_msg("_kernelrpc_mach_port_move_member_trap() -> KERN_INVALID_RIGHT\n"); 564 + 565 + ret = KERN_INVALID_RIGHT; 566 + goto err; 567 + } 568 + 569 + if (args.pset_right_name != 0) 570 + { 571 + right_pset = ipc_space_lookup(&task->namespace, args.pset_right_name); 572 + if (right_pset == NULL || right_pset->type != MACH_PORT_RIGHT_RECEIVE) 573 + { 574 + debug_msg("_kernelrpc_mach_port_move_member_trap() -> KERN_INVALID_RIGHT\n"); 575 + 576 + ret = KERN_INVALID_RIGHT; 577 + goto err; 578 + } 579 + } 580 + 581 + ret = ipc_portset_extract(right_pset ? right_pset->port : NULL, right_port->port); 582 + 583 + err: 584 + if (right_port != NULL) 585 + ipc_port_unlock(right_port->port); 586 + if (right_pset != NULL) 587 + ipc_port_unlock(right_pset->port); 588 + 589 + ipc_space_unlock(&task->namespace); 590 + return ret; 591 + } 592 + 426 593 kern_return_t _kernelrpc_mach_port_deallocate_trap(mach_task_t* task, 427 594 struct mach_port_deallocate_args* in_args) 428 595 { ··· 444 611 } 445 612 446 613 right = ipc_space_lookup(&task->namespace, args.port_right_name); 447 - if (right == NULL || right->type == MACH_PORT_RIGHT_RECEIVE) 614 + if (right == NULL || right->type != MACH_PORT_RIGHT_RECEIVE) 448 615 { 449 616 debug_msg("_kernelrpc_mach_port_deallocate_trap() -> KERN_INVALID_RIGHT\n"); 450 617 ··· 513 680 514 681 if (copy_from_user(&args, in_args, sizeof(args))) 515 682 { 516 - debug_msg("!!! Cannot copy %d bytes from %p\n", 683 + debug_msg("!!! Cannot copy %lu bytes from %p\n", 517 684 sizeof(args), in_args); 518 685 return KERN_INVALID_ADDRESS; 519 686 }
+6
src/lkm/traps.h
··· 42 42 struct mach_port_allocate_args* args); 43 43 kern_return_t mach_msg_overwrite_trap(mach_task_t* task, 44 44 struct mach_msg_overwrite_args* args); 45 + kern_return_t _kernelrpc_mach_port_move_member_trap(mach_task_t* task, 46 + struct mach_port_move_member_args* in_args); 47 + kern_return_t _kernelrpc_mach_port_insert_member_trap(mach_task_t* task, 48 + struct mach_port_insert_member_args* in_args); 49 + kern_return_t _kernelrpc_mach_port_extract_member_trap(mach_task_t* task, 50 + struct mach_port_extract_member_args* in_args); 45 51 46 52 kern_return_t semaphore_signal_trap(mach_task_t* task, 47 53 struct semaphore_signal_args* args);