X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..4a3eedf9ecc9bbe3f3a5c6ce5e53ad199d639d32:/osfmk/ipc/ipc_right.c diff --git a/osfmk/ipc/ipc_right.c b/osfmk/ipc/ipc_right.c index 3a06a1c97..1d9d16596 100644 --- a/osfmk/ipc/ipc_right.c +++ b/osfmk/ipc/ipc_right.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2002,2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_FREE_COPYRIGHT@ @@ -50,6 +53,13 @@ * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + * Copyright (c) 2005-2006 SPARTA, Inc. + */ /* */ /* @@ -76,6 +86,7 @@ #include #include #include +#include /* * Routine: ipc_right_lookup_write @@ -385,10 +396,10 @@ ipc_right_dnrequest( ipc_port_t ipc_right_dncancel( - ipc_space_t space, - ipc_port_t port, - mach_port_name_t name, - ipc_entry_t entry) + __unused ipc_space_t space, + ipc_port_t port, + mach_port_name_t name, + ipc_entry_t entry) { ipc_port_t dnrequest; @@ -413,9 +424,9 @@ ipc_right_dncancel( boolean_t ipc_right_inuse( - ipc_space_t space, - mach_port_name_t name, - ipc_entry_t entry) + ipc_space_t space, + __unused mach_port_name_t name, + ipc_entry_t entry) { if (IE_BITS_TYPE(entry->ie_bits) != MACH_PORT_TYPE_NONE) { is_write_unlock(space); @@ -561,7 +572,7 @@ ipc_right_clean( ipc_port_t port = (ipc_port_t) entry->ie_object; ipc_port_t dnrequest; ipc_port_t nsrequest = IP_NULL; - mach_port_mscount_t mscount; + mach_port_mscount_t mscount = 0; assert(port != IP_NULL); ip_lock(port); @@ -674,7 +685,7 @@ ipc_right_destroy( case MACH_PORT_TYPE_SEND_ONCE: { ipc_port_t port = (ipc_port_t) entry->ie_object; ipc_port_t nsrequest = IP_NULL; - mach_port_mscount_t mscount; + mach_port_mscount_t mscount = 0; ipc_port_t dnrequest; assert(port != IP_NULL); @@ -831,7 +842,7 @@ ipc_right_dealloc( ipc_port_t port; ipc_port_t dnrequest = IP_NULL; ipc_port_t nsrequest = IP_NULL; - mach_port_mscount_t mscount; + mach_port_mscount_t mscount = 0; assert(IE_BITS_UREFS(bits) > 0); @@ -884,7 +895,7 @@ ipc_right_dealloc( case MACH_PORT_TYPE_SEND_RECEIVE: { ipc_port_t port; ipc_port_t nsrequest = IP_NULL; - mach_port_mscount_t mscount; + mach_port_mscount_t mscount = 0; assert(IE_BITS_UREFS(bits) > 0); @@ -1160,7 +1171,7 @@ ipc_right_delta( ipc_port_t port; ipc_port_t dnrequest = IP_NULL; ipc_port_t nsrequest = IP_NULL; - mach_port_mscount_t mscount; + mach_port_mscount_t mscount = 0; if ((bits & MACH_PORT_TYPE_SEND) == 0) goto invalid_right; @@ -1313,29 +1324,72 @@ ipc_right_info( boolean_t ipc_right_copyin_check( - ipc_space_t space, - mach_port_name_t name, - ipc_entry_t entry, - mach_msg_type_name_t msgt_name) + __assert_only ipc_space_t space, + __unused mach_port_name_t name, + ipc_entry_t entry, + mach_msg_type_name_t msgt_name) { ipc_entry_bits_t bits; + ipc_port_t port; +#if CONFIG_MACF_MACH + task_t self = current_task(); + int rc = 0; +#endif bits= entry->ie_bits; assert(space->is_active); switch (msgt_name) { case MACH_MSG_TYPE_MAKE_SEND: + if ((bits & MACH_PORT_TYPE_RECEIVE) == 0) + return FALSE; + +#if CONFIG_MACF_MACH + port = (ipc_port_t) entry->ie_object; + ip_lock(port); + tasklabel_lock(self); + rc = mac_port_check_make_send(&self->maclabel, &port->ip_label); tasklabel_unlock(self); + ip_unlock(port); + if (rc) + return FALSE; +#endif + break; + case MACH_MSG_TYPE_MAKE_SEND_ONCE: + if ((bits & MACH_PORT_TYPE_RECEIVE) == 0) + return FALSE; + +#if CONFIG_MACF_MACH + port = (ipc_port_t) entry->ie_object; + ip_lock(port); + tasklabel_lock(self); + rc = mac_port_check_make_send_once(&self->maclabel, &port->ip_label); + tasklabel_unlock(self); + ip_unlock(port); + if (rc) + return FALSE; +#endif + break; + case MACH_MSG_TYPE_MOVE_RECEIVE: if ((bits & MACH_PORT_TYPE_RECEIVE) == 0) return FALSE; +#if CONFIG_MACF_MACH + port = (ipc_port_t) entry->ie_object; + ip_lock(port); + tasklabel_lock(self); + rc = mac_port_check_move_receive(&self->maclabel, &port->ip_label); + tasklabel_unlock(self); + ip_unlock(port); + if (rc) + return FALSE; +#endif break; case MACH_MSG_TYPE_COPY_SEND: case MACH_MSG_TYPE_MOVE_SEND: case MACH_MSG_TYPE_MOVE_SEND_ONCE: { - ipc_port_t port; boolean_t active; if (bits & MACH_PORT_TYPE_DEAD_NAME) @@ -1349,6 +1403,30 @@ ipc_right_copyin_check( ip_lock(port); active = ip_active(port); +#if CONFIG_MACF_MACH + tasklabel_lock(self); + switch (msgt_name) { + case MACH_MSG_TYPE_COPY_SEND: + rc = mac_port_check_copy_send(&self->maclabel, + &port->ip_label); + break; + case MACH_MSG_TYPE_MOVE_SEND: + rc = mac_port_check_move_send(&self->maclabel, + &port->ip_label); + break; + case MACH_MSG_TYPE_MOVE_SEND_ONCE: + rc = mac_port_check_move_send_once(&self->maclabel, + &port->ip_label); + break; + default: + panic("ipc_right_copyin_check: strange rights"); + } + tasklabel_unlock(self); + if (rc) { + ip_unlock(port); + return FALSE; + } +#endif ip_unlock(port); if (!active) { @@ -1407,6 +1485,10 @@ ipc_right_copyin( ipc_port_t *sorightp) { ipc_entry_bits_t bits; +#if CONFIG_MACF_MACH + task_t self = current_task(); + int rc; +#endif bits = entry->ie_bits; @@ -1427,6 +1509,16 @@ ipc_right_copyin( assert(port->ip_receiver_name == name); assert(port->ip_receiver == space); +#if CONFIG_MACF_MACH + tasklabel_lock(self); + rc = mac_port_check_make_send(&self->maclabel, &port->ip_label); + tasklabel_unlock(self); + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } +#endif + port->ip_mscount++; port->ip_srights++; ip_reference(port); @@ -1451,6 +1543,16 @@ ipc_right_copyin( assert(port->ip_receiver_name == name); assert(port->ip_receiver == space); +#if CONFIG_MACF_MACH + tasklabel_lock(self); + rc = mac_port_check_make_send_once(&self->maclabel, &port->ip_label); + tasklabel_unlock(self); + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } +#endif + port->ip_sorights++; ip_reference(port); ip_unlock(port); @@ -1475,6 +1577,17 @@ ipc_right_copyin( assert(port->ip_receiver_name == name); assert(port->ip_receiver == space); +#if CONFIG_MACF_MACH + tasklabel_lock(self); + rc = mac_port_check_move_receive(&self->maclabel, + &port->ip_label); + tasklabel_unlock(self); + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } +#endif + if (bits & MACH_PORT_TYPE_SEND) { assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_RECEIVE); @@ -1527,6 +1640,16 @@ ipc_right_copyin( } /* port is locked and active */ +#if CONFIG_MACF_MACH + tasklabel_lock(self); + rc = mac_port_check_copy_send(&self->maclabel, &port->ip_label); + tasklabel_unlock(self); + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } +#endif + if ((bits & MACH_PORT_TYPE_SEND) == 0) { assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_ONCE); assert(port->ip_sorights > 0); @@ -1569,6 +1692,17 @@ ipc_right_copyin( } /* port is locked and active */ +#if CONFIG_MACF_MACH + tasklabel_lock (self); + rc = mac_port_check_copy_send (&self->maclabel, &port->ip_label); + tasklabel_unlock (self); + if (rc) + { + ip_unlock (port); + return KERN_NO_ACCESS; + } +#endif + if ((bits & MACH_PORT_TYPE_SEND) == 0) { assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_ONCE); assert(port->ip_sorights > 0); @@ -1635,6 +1769,17 @@ ipc_right_copyin( } /* port is locked and active */ +#if CONFIG_MACF_MACH + tasklabel_lock (self); + rc = mac_port_check_copy_send (&self->maclabel, &port->ip_label); + tasklabel_unlock (self); + if (rc) + { + ip_unlock (port); + return KERN_NO_ACCESS; + } +#endif + if ((bits & MACH_PORT_TYPE_SEND_ONCE) == 0) { assert(bits & MACH_PORT_TYPE_SEND); assert(port->ip_srights > 0); @@ -1806,6 +1951,10 @@ ipc_right_copyin_two( mach_port_urefs_t urefs; ipc_port_t port; ipc_port_t dnrequest = IP_NULL; +#if CONFIG_MACF_MACH + task_t self = current_task(); + int rc; +#endif assert(space->is_active); @@ -1826,6 +1975,16 @@ ipc_right_copyin_two( } /* port is locked and active */ +#if CONFIG_MACF_MACH + tasklabel_lock(self); + rc = mac_port_check_copy_send(&self->maclabel, &port->ip_label); + tasklabel_unlock(self); + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } +#endif + assert(port->ip_srights > 0); if (urefs == 2) { @@ -1902,6 +2061,9 @@ ipc_right_copyout( { ipc_entry_bits_t bits; ipc_port_t port; +#if CONFIG_MACF_MACH + int rc; +#endif bits = entry->ie_bits; @@ -1918,6 +2080,19 @@ ipc_right_copyout( assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_NONE); assert(port->ip_sorights > 0); +#if CONFIG_MACF_MACH + if (space->is_task) { + tasklabel_lock(space->is_task); + rc = mac_port_check_hold_send_once(&space->is_task->maclabel, + &port->ip_label); + tasklabel_unlock(space->is_task); + + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } + } +#endif /* transfer send-once right and ref to entry */ ip_unlock(port); @@ -1927,6 +2102,20 @@ ipc_right_copyout( case MACH_MSG_TYPE_PORT_SEND: assert(port->ip_srights > 0); +#if CONFIG_MACF_MACH + if (space->is_task) { + tasklabel_lock(space->is_task); + rc = mac_port_check_hold_send(&space->is_task->maclabel, + &port->ip_label); + tasklabel_unlock(space->is_task); + + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } + } +#endif + if (bits & MACH_PORT_TYPE_SEND) { mach_port_urefs_t urefs = IE_BITS_UREFS(bits); @@ -1981,6 +2170,20 @@ ipc_right_copyout( assert(port->ip_receiver_name == MACH_PORT_NULL); dest = port->ip_destination; +#if CONFIG_MACF_MACH + if (space->is_task) { + tasklabel_lock(space->is_task); + rc = mac_port_check_hold_receive(&space->is_task->maclabel, + &port->ip_label); + tasklabel_unlock(space->is_task); + + if (rc) { + ip_unlock(port); + return KERN_NO_ACCESS; + } + } +#endif + port->ip_receiver_name = name; port->ip_receiver = space;