error_t setup_thread_target (void) { error_t err; static task_t task; static thread_t thread; if (MACH_PORT_VALID (thread)) { thread_terminate (thread); mach_port_deallocate (mach_task_self (), thread); } if (MACH_PORT_VALID (task)) { task_terminate (task); mach_port_deallocate (mach_task_self (), task); } err = task_create (mach_task_self (), 0, &task); if (err) return err; err = thread_create (task, &thread); if (err) return err; return setup (thread, MACH_MSG_TYPE_COPY_SEND); }
error_t setup_proc_target (void) { error_t err; static task_t task; static process_t proc, target; static mach_msg_type_name_t targetType = MACH_MSG_TYPE_COPY_SEND; if (! MACH_PORT_VALID (proc)) proc = getproc (); if (MACH_PORT_VALID (task)) mach_port_deallocate (mach_task_self (), task); if (MACH_PORT_VALID (target)) mach_port_deallocate (mach_task_self (), target); err = task_create (mach_task_self (), 0, &task); if (err) return err; err = proc_task2proc (proc, task, &target); if (err) return err; return setup (target, targetType); }
kern_return_t mach_port_extract_member( ipc_space_t space, mach_port_name_t name, mach_port_name_t psname) { mach_port_name_t oldname; ipc_object_t psobj; ipc_object_t obj; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (!MACH_PORT_VALID(name) || !MACH_PORT_VALID(psname)) return KERN_INVALID_RIGHT; kr = ipc_object_translate_two(space, name, MACH_PORT_RIGHT_RECEIVE, &obj, psname, MACH_PORT_RIGHT_PORT_SET, &psobj); if (kr != KERN_SUCCESS) return kr; /* obj and psobj are both locked (and were locked in that order) */ assert(psobj != IO_NULL); assert(obj != IO_NULL); kr = ipc_pset_remove((ipc_pset_t)psobj, (ipc_port_t)obj); io_unlock(psobj); io_unlock(obj); return kr; }
error_t increase_priority (void) { mach_port_t pset = MACH_PORT_NULL, psetcntl = MACH_PORT_NULL; error_t err; err = thread_get_assignment (mach_thread_self (), &pset); if (err) goto out; err = host_processor_set_priv (_hurd_host_priv, pset, &psetcntl); if (err) goto out; err = thread_max_priority (mach_thread_self (), psetcntl, 0); if (err) goto out; err = task_priority (mach_task_self (), 2, 1); out: if (MACH_PORT_VALID (pset)) mach_port_deallocate (mach_task_self (), pset); if (MACH_PORT_VALID (psetcntl)) mach_port_deallocate (mach_task_self (), psetcntl); return err; }
kern_return_t mach_port_set_attributes( ipc_space_t space, mach_port_name_t name, int flavor, mach_port_info_t info, mach_msg_type_number_t count) { ipc_port_t port; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; switch (flavor) { case MACH_PORT_LIMITS_INFO: { mach_port_limits_t *mplp = (mach_port_limits_t *)info; if (count < MACH_PORT_LIMITS_INFO_COUNT) return KERN_FAILURE; if (mplp->mpl_qlimit > MACH_PORT_QLIMIT_MAX) return KERN_INVALID_VALUE; if (!MACH_PORT_VALID(name)) return KERN_INVALID_RIGHT; kr = ipc_port_translate_receive(space, name, &port); if (kr != KERN_SUCCESS) return kr; /* port is locked and active */ ipc_mqueue_set_qlimit(&port->ip_messages, mplp->mpl_qlimit); ip_unlock(port); break; } case MACH_PORT_DNREQUESTS_SIZE: { if (count < MACH_PORT_DNREQUESTS_SIZE_COUNT) return KERN_FAILURE; if (!MACH_PORT_VALID(name)) return KERN_INVALID_RIGHT; kr = ipc_port_translate_receive(space, name, &port); if (kr != KERN_SUCCESS) return kr; /* port is locked and active */ kr = ipc_port_dngrow(port, *(int *)info); if (kr != KERN_SUCCESS) return kr; break; } default: return KERN_INVALID_ARGUMENT; /*NOTREACHED*/ } return KERN_SUCCESS; }
extern void ProtThreadRegister(Bool setup) { kern_return_t kr; mach_msg_type_number_t old_exception_count = 1; exception_mask_t old_exception_masks; exception_behavior_t behavior; mach_port_t old_exception_ports; exception_behavior_t old_behaviors; thread_state_flavor_t old_flavors; mach_port_t self; static mach_port_t setupThread = MACH_PORT_NULL; self = mach_thread_self(); AVER(MACH_PORT_VALID(self)); /* Avoid setting up the exception handler for the thread that calls ProtSetup twice, in the case where the mutator registers that thread explicitly. We need a special case because we don't require thread registration of the sole thread of a single-threaded mutator. */ if (setup) { AVER(setupThread == MACH_PORT_NULL); setupThread = self; } else { AVER(setupThread != MACH_PORT_NULL); if (self == setupThread) return; } /* Ask to receive EXC_BAD_ACCESS exceptions on our port, complete with thread state and identity information in the message. The MACH_EXCEPTION_CODES flag causes the code fields to be passed 64-bits wide, matching protRequestStruct [Fuller_2013]. */ behavior = (exception_behavior_t)(EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES); AVER(MACH_PORT_VALID(protExcPort)); kr = thread_swap_exception_ports(self, EXC_MASK_BAD_ACCESS, protExcPort, behavior, THREAD_STATE_FLAVOR, &old_exception_masks, &old_exception_count, &old_exception_ports, &old_behaviors, &old_flavors); AVER(kr == KERN_SUCCESS); if (kr != KERN_SUCCESS) mach_error("ERROR: MPS thread_swap_exception_ports", kr); /* .trans.must */ AVER(old_exception_masks == EXC_MASK_BAD_ACCESS); AVER(old_exception_count == 1); AVER(old_exception_ports == MACH_PORT_NULL || old_exception_ports == protExcPort); /* .assume.only-port */ }
error_t setup_auth_target (void) { static auth_t auth; static mach_msg_type_name_t authType = MACH_MSG_TYPE_COPY_SEND; if (MACH_PORT_VALID (auth)) mach_port_deallocate (mach_task_self (), auth); auth = getauth (); if (! MACH_PORT_VALID (auth)) return errno; return setup (auth, authType); }
memory_object_t inode_pager_setup( struct inode *inode) { struct i_mem_object *imo; if (inode == NULL) return MEMORY_OBJECT_NULL; imo = inode->i_mem_object; if (imo == NULL) { /* * First time this inode is mapped. Create a memory object. */ imo = imo_create(inode, TRUE); if (imo == NULL) return MEMORY_OBJECT_NULL; } imo_ref(imo); /* 1 ref for the mapper */ #ifdef INODE_PAGER_DEBUG if (inode_pager_debug) { printk("inode_pager_setup: imo 0x%p: obj 0x%x, inode 0x%p\n", imo, imo->imo_mem_obj, imo->imo_inode); } #endif /* INODE_PAGER_DEBUG */ ASSERT(MACH_PORT_VALID(imo->imo_mem_obj)); return imo->imo_mem_obj; }
void osfmach3_get_time( struct timeval *xtime) { tvalspec_t cur_time; #ifdef __powerpc__ if (use_highres && MACH_PORT_VALID(rt_clock)) { kern_return_t kr; /* * We want a higher resolution time: ask the microkernel. * XXX this doesn't work on MP PowerMac systems. */ kr = clock_get_time(rt_clock, &cur_time); if (kr != KERN_SUCCESS) { MACH3_DEBUG(2, kr, ("osfmach3_get_time: clock_get_time(0x%x)", rt_clock)); /* use mapped time */ MTS_TO_TS(serv_mtime, &cur_time); } } else { MTS_TO_TS(serv_mtime, &cur_time); } #else /* __powerpc__ */ MTS_TO_TS(serv_mtime, &cur_time); #endif /* __powerpc__ */ xtime->tv_sec = cur_time.tv_sec + base_time.tv_sec; xtime->tv_usec = (cur_time.tv_nsec + base_time.tv_nsec) / 1000; if (xtime->tv_usec >= USEC_PER_SEC) { xtime->tv_sec++; xtime->tv_usec -= USEC_PER_SEC; } }
kern_return_t mach_port_set_seqno( ipc_space_t space, mach_port_name_t name, mach_port_seqno_t seqno) { ipc_port_t port; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (!MACH_PORT_VALID(name)) return KERN_INVALID_RIGHT; kr = ipc_port_translate_receive(space, name, &port); if (kr != KERN_SUCCESS) return kr; /* port is locked and active */ ipc_mqueue_set_seqno(&port->ip_messages, seqno); ip_unlock(port); return KERN_SUCCESS; }
kern_return_t mach_port_set_mscount( ipc_space_t space, mach_port_name_t name, mach_port_mscount_t mscount) { ipc_port_t port; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (!MACH_PORT_VALID(name)) return KERN_INVALID_RIGHT; kr = ipc_port_translate_receive(space, name, &port); if (kr != KERN_SUCCESS) return kr; /* port is locked and active */ ipc_port_set_mscount(port, mscount); ip_unlock(port); return KERN_SUCCESS; }
kern_return_t mach_port_mod_refs( ipc_space_t space, mach_port_name_t name, mach_port_right_t right, mach_port_delta_t delta) { ipc_entry_t entry; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (right >= MACH_PORT_RIGHT_NUMBER) return KERN_INVALID_VALUE; if (!MACH_PORT_VALID(name)) { if (right == MACH_PORT_RIGHT_SEND || right == MACH_PORT_RIGHT_SEND_ONCE) return KERN_SUCCESS; return KERN_INVALID_NAME; } kr = ipc_right_lookup_write(space, name, &entry); if (kr != KERN_SUCCESS) return kr; /* space is write-locked and active */ kr = ipc_right_delta(space, name, entry, right, delta); /* unlocks */ return kr; }
kern_return_t mach_port_extract_right( ipc_space_t space, mach_port_name_t name, mach_msg_type_name_t msgt_name, ipc_port_t *poly, mach_msg_type_name_t *polyPoly) { kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (!MACH_MSG_TYPE_PORT_ANY(msgt_name)) return KERN_INVALID_VALUE; if (!MACH_PORT_VALID(name)) { /* * really should copy out a dead name, if it is a send or * send-once right being copied, but instead return an * error for now. */ return KERN_INVALID_RIGHT; } kr = ipc_object_copyin(space, name, msgt_name, (ipc_object_t *) poly); if (kr == KERN_SUCCESS) *polyPoly = ipc_object_copyin_type(msgt_name); return kr; }
Res ThreadRegister(Thread *threadReturn, Arena arena) { Res res; Thread thread; Ring ring; void *p; AVER(threadReturn != NULL); res = ControlAlloc(&p, arena, sizeof(ThreadStruct)); if (res != ResOK) return res; thread = (Thread)p; thread->arena = arena; RingInit(&thread->arenaRing); thread->serial = arena->threadSerial; ++arena->threadSerial; thread->alive = TRUE; thread->forking = FALSE; thread->port = mach_thread_self(); AVER(MACH_PORT_VALID(thread->port)); thread->sig = ThreadSig; AVERT(Thread, thread); ProtThreadRegister(); ring = ArenaThreadRing(arena); RingAppend(ring, &thread->arenaRing); *threadReturn = thread; return ResOK; }
int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; argp_parse (&argp, argc, argv, 0, 0, 0); if (MACH_PORT_VALID (opt_device_master)) { err = open_console (opt_device_master); assert_perror (err); mach_port_deallocate (mach_task_self (), opt_device_master); } save_argv = argv; task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (2, 0, "Must be started as a translator"); /* Fetch our proc server port for easy use. If we are booting, it is not set yet and `getproc' returns MACH_PORT_NULL; we reset PROCSERVER in S_exec_init (below). */ procserver = getproc (); err = trivfs_add_port_bucket (&port_bucket); if (err) error (1, 0, "error creating port bucket"); err = trivfs_add_control_port_class (&trivfs_control_class); if (err) error (1, 0, "error creating control port class"); err = trivfs_add_protid_port_class (&trivfs_protid_class); if (err) error (1, 0, "error creating protid port class"); execboot_portclass = ports_create_class (deadboot, NULL); /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, trivfs_control_class, port_bucket, trivfs_protid_class, port_bucket, &fsys); /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, trivfs_control_class, port_bucket, trivfs_protid_class, port_bucket, &fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error (3, err, "Contacting parent"); /* Launch. */ ports_manage_port_operations_multithread (port_bucket, exec_demuxer, 2 * 60 * 1000, 0, 0); return 0; }
static task_t pid_to_task(int pid) { task_t task = 0; static task_t old_task = 0; static int old_pid = -1; kern_return_t kr; if (old_task != 0 && old_pid == pid) { return old_task; } else if (old_task != 0 && old_pid != pid) { //we changed the process pid so deallocate a ref from the old_task //since we are going to get a new task kr = mach_port_deallocate (mach_task_self (), old_task); if (kr != KERN_SUCCESS) { eprintf ("pid_to_task: fail to deallocate port\n"); return 0; } } int err = task_for_pid (mach_task_self (), (pid_t)pid, &task); if ((err != KERN_SUCCESS) || !MACH_PORT_VALID (task)) { task = task_for_pid_workaround (pid); if (task == MACH_PORT_NULL) { task = task_for_pid_ios9pangu (pid); if (task != MACH_PORT_NULL) { //eprintf ("Failed to get task %d for pid %d.\n", (int)task, (int)pid); //eprintf ("Missing priviledges? 0x%x: %s\n", err, MACH_ERROR_STRING (err)); return -1; } } } old_task = task; old_pid = pid; return task; }
EXTERN io_object_t iokit_lookup_connect_ref(io_object_t connectRef, ipc_space_t space) { io_object_t obj = NULL; if (connectRef && MACH_PORT_VALID(CAST_MACH_PORT_TO_NAME(connectRef))) { ipc_port_t port; kern_return_t kr; kr = ipc_object_translate(space, CAST_MACH_PORT_TO_NAME(connectRef), MACH_PORT_RIGHT_SEND, (ipc_object_t *)&port); if (kr == KERN_SUCCESS) { assert(IP_VALID(port)); ip_reference(port); ip_unlock(port); iokit_lock_port(port); if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_CONNECT)) { obj = (io_object_t) port->ip_kobject; iokit_add_connect_reference(obj); } iokit_unlock_port(port); ip_release(port); } } return obj; }
/* * Routine: port_name_to_semaphore * Purpose: * Convert from a port name in the current space to a semaphore. * Produces a semaphore ref, which may be null. * Conditions: * Nothing locked. */ kern_return_t port_name_to_semaphore( mach_port_name_t name, semaphore_t *semaphorep) { ipc_port_t kern_port; kern_return_t kr; if (!MACH_PORT_VALID(name)) { *semaphorep = SEMAPHORE_NULL; return KERN_INVALID_NAME; } kr = ipc_object_translate(current_space(), name, MACH_PORT_RIGHT_SEND, (ipc_object_t *) &kern_port); if (kr != KERN_SUCCESS) { *semaphorep = SEMAPHORE_NULL; return kr; } /* have the port locked */ assert(IP_VALID(kern_port)); *semaphorep = convert_port_to_semaphore(kern_port); ip_unlock(kern_port); return KERN_SUCCESS; }
task_t pid_to_task(int pid) { static task_t old_pid = -1; static task_t old_task = -1; task_t task = -1; int err; /* xlr8! */ if (old_task != -1 && old_pid == pid) return old_task; err = task_for_pid (mach_task_self (), (pid_t)pid, &task); if ((err != KERN_SUCCESS) || !MACH_PORT_VALID (task)) { task = task_for_pid_workaround (pid); if (task == -1) { eprintf ("Failed to get task %d for pid %d.\n", (int)task, (int)pid); eprintf ("Reason: 0x%x: %s\n", err, (char *)MACH_ERROR_STRING (err)); eprintf ("You probably need to run as root or sign the binary.\n" " Read doc/ios.md || doc/osx.md\n" " make -C binr/radare2 ios-sign || osx-sign\n"); return -1; } } old_pid = pid; old_task = task; return task; }
int main() { mach_port_t process_to_write; kern_return_t error; if(getuid() && geteuid()) { printf("You need to be root to vm_write!\n"); } else{ error = task_for_pid(mach_task_self(), PID, &process_to_write); if ((error != KERN_SUCCESS) || !MACH_PORT_VALID(process_to_write)) { printf("Error getting the process!\n"); } mach_port_name_t task; vm_map_offset_t vmoffset; vm_map_size_t vmsize; uint32_t nesting_depth = 0; struct vm_region_submap_info_64 vbr; mach_msg_type_number_t vbrcount = 16; kern_return_t kr; if ((kr = mach_vm_region_recurse(process_to_write, &vmoffset, &vmsize, &nesting_depth, (vm_region_recurse_info_t)&vbr, &vbrcount)) != KERN_SUCCESS) { printf("Error"); } printf("%p\n", (void *) (uintptr_t)vmoffset); } return 0; }
kern_return_t mach_port_rename( ipc_space_t space, mach_port_name_t oname, mach_port_name_t nname) { if (space == IS_NULL) return KERN_INVALID_TASK; if (!MACH_PORT_VALID(oname)) return KERN_INVALID_NAME; if (!MACH_PORT_VALID(nname)) return KERN_INVALID_VALUE; return ipc_object_rename(space, oname, nname); }
Bool ThreadCheck(Thread thread) { CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); CHECKL(RingCheck(&thread->arenaRing)); CHECKL(MACH_PORT_VALID(thread->port)); return TRUE; }
error_t setup (mach_port_t request, mach_msg_type_name_t requestType) { RequestTemplate.Head.msgh_remote_port = request; if (! MACH_PORT_VALID (RequestTemplate.Head.msgh_local_port)) RequestTemplate.Head.msgh_local_port = mach_reply_port (); RequestTemplate.Head.msgh_bits = MACH_MSGH_BITS (requestType, MACH_MSG_TYPE_MAKE_SEND_ONCE); return 0; }
Bool ThreadCheck(Thread thread) { CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); CHECKD_NOSIG(Ring, &thread->arenaRing); CHECKL(BoolCheck(thread->alive)); CHECKL(BoolCheck(thread->forking)); CHECKL(MACH_PORT_VALID(thread->port)); return TRUE; }
static void protSetupInner(void) { kern_return_t kr; int pr; pthread_t excThread; mach_port_t self; /* Create a port to send and receive exceptions. */ self = mach_task_self(); AVER(MACH_PORT_VALID(self)); kr = mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &protExcPort); AVER(kr == KERN_SUCCESS); if (kr != KERN_SUCCESS) mach_error("ERROR: MPS mach_port_allocate", kr); /* .trans.must */ AVER(MACH_PORT_VALID(protExcPort)); /* Allow me to send exceptions on this port. */ /* TODO: Find out why this is necessary. */ self = mach_task_self(); AVER(MACH_PORT_VALID(self)); kr = mach_port_insert_right(self, protExcPort, protExcPort, MACH_MSG_TYPE_MAKE_SEND); AVER(kr == KERN_SUCCESS); if (kr != KERN_SUCCESS) mach_error("ERROR: MPS mach_port_insert_right", kr); /* .trans.must */ ProtThreadRegister(TRUE); /* Launch the exception handling thread. We use pthread_create because it's much simpler than setting up a thread from scratch using Mach, and that's basically what it does. See [Libc] <http://www.opensource.apple.com/source/Libc/Libc-825.26/pthreads/pthread.c> */ pr = pthread_create(&excThread, NULL, protCatchThread, NULL); AVER(pr == 0); if (pr != 0) fprintf(stderr, "ERROR: MPS pthread_create: %d\n", pr); /* .trans.must */ }
static task_t pid_to_task(int pid) { task_t task = 0; int err = task_for_pid (mach_task_self (), (pid_t)pid, &task); if ((err != KERN_SUCCESS) || !MACH_PORT_VALID (task)) { eprintf ("Failed to get task %d for pid %d.\n", (int)task, (int)pid); eprintf ("Reason: 0x%x: %s\n", err, MACH_ERROR_STRING (err)); eprintf ("You probably need to add user to procmod group.\n" " Or chmod g+s radare && chown root:procmod radare\n"); eprintf ("FMI: http://developer.apple.com/documentation/Darwin/Reference/ManPages/man8/taskgated.8.html\n"); return -1; } return task; }
/* Called by MiG to deallocate the reply port. */ void __mig_dealloc_reply_port (mach_port_t arg) { mach_port_t port; GETPORT; port = reply_port; reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */ if (MACH_PORT_VALID (port)) __mach_port_mod_refs (__mach_task_self (), port, MACH_PORT_RIGHT_RECEIVE, -1); }
int32_t k5_ipc_server_send_reply (mach_port_t in_reply_port, k5_ipc_stream in_reply_stream) { kern_return_t err = KERN_SUCCESS; k5_ipc_inl_reply_t inl_reply; mach_msg_type_number_t inl_reply_length = 0; k5_ipc_ool_reply_t ool_reply = NULL; mach_msg_type_number_t ool_reply_length = 0; if (!MACH_PORT_VALID (in_reply_port)) { err = EINVAL; } if (!in_reply_stream ) { err = EINVAL; } if (!err) { /* depending on how big the message is, use the fast inline buffer or * the slow dynamically allocated buffer */ mach_msg_type_number_t reply_length = krb5int_ipc_stream_size (in_reply_stream); if (reply_length > K5_IPC_MAX_INL_MSG_SIZE) { //dprintf ("%s choosing out of line buffer (size is %d)", // __FUNCTION__, reply_length); err = vm_read (mach_task_self (), (vm_address_t) krb5int_ipc_stream_data (in_reply_stream), reply_length, (vm_address_t *) &ool_reply, &ool_reply_length); } else { //cci_debug_printf ("%s choosing in line buffer (size is %d)", // __FUNCTION__, reply_length); inl_reply_length = reply_length; memcpy (inl_reply, krb5int_ipc_stream_data (in_reply_stream), reply_length); } } if (!err) { err = k5_ipc_server_reply (in_reply_port, inl_reply, inl_reply_length, ool_reply, ool_reply_length); } if (!err) { /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ ool_reply = NULL; ool_reply_length = 0; } if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } return err; }
error_t setup_hurd_target (void) { char *name = (char *) setup_argument; mach_port_t request; mach_msg_type_name_t requestType; request = file_name_lookup (name, 0, 0); if (! MACH_PORT_VALID (request)) return errno; requestType = MACH_MSG_TYPE_COPY_SEND; return setup (request, requestType); }
kern_return_t mach_set_port_label( ipc_space_t space, mach_port_name_t name, vm_offset_t labelstr) { #ifdef MAC ipc_entry_t entry; kern_return_t kr; struct label inl; int rc; if (space == IS_NULL || space->is_task == NULL) return KERN_INVALID_TASK; if (!MACH_PORT_VALID(name)) return KERN_INVALID_NAME; mac_init_port_label(&inl); rc = mac_internalize_port_label(&inl, labelstr); if (rc) return KERN_INVALID_ARGUMENT; kr = ipc_right_lookup_write(space, name, &entry); if (kr != KERN_SUCCESS) return kr; if (io_otype(entry->ie_object) != IOT_PORT) { is_write_unlock(space); return KERN_INVALID_RIGHT; } ipc_port_t port = (ipc_port_t) entry->ie_object; ip_lock(port); rc = mac_check_port_relabel(&space->is_task->maclabel, &port->ip_label, &inl); if (rc) kr = KERN_NO_ACCESS; else mac_copy_port_label(&inl, &port->ip_label); ip_unlock(port); is_write_unlock(space); return kr; #else return KERN_INVALID_ARGUMENT; #endif }