X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..490019cf9519204c5fb36b2fba54ceb983bb6b72:/osfmk/kern/ipc_host.c diff --git a/osfmk/kern/ipc_host.c b/osfmk/kern/ipc_host.c index 65f1035fe..88e629de4 100644 --- a/osfmk/kern/ipc_host.c +++ b/osfmk/kern/ipc_host.c @@ -67,7 +67,6 @@ #include #include #include -#include #include #include #include @@ -77,6 +76,10 @@ #include #include +#if CONFIG_MACF +#include +#endif + /* * Forward declarations */ @@ -534,7 +537,7 @@ convert_port_to_host_security( */ kern_return_t host_set_exception_ports( - host_priv_t host_priv, + host_priv_t host_priv, exception_mask_t exception_mask, ipc_port_t new_port, exception_behavior_t new_behavior, @@ -547,8 +550,6 @@ host_set_exception_ports( return KERN_INVALID_ARGUMENT; } - assert(host_priv == &realhost); - if (exception_mask & ~EXC_MASK_VALID) { return KERN_INVALID_ARGUMENT; } @@ -563,10 +564,22 @@ host_set_exception_ports( return KERN_INVALID_ARGUMENT; } } - /* Cannot easily check "new_flavor", but that just means that - * the flavor in the generated exception message might be garbage: - * GIGO + + /* + * Check the validity of the thread_state_flavor by calling the + * VALID_THREAD_STATE_FLAVOR architecture dependent macro defined in + * osfmk/mach/ARCHITECTURE/thread_status.h */ + if (new_flavor != 0 && !VALID_THREAD_STATE_FLAVOR(new_flavor)) + return (KERN_INVALID_ARGUMENT); + +#if CONFIG_MACF + if (mac_task_check_set_host_exception_ports(current_task(), exception_mask) != 0) + return KERN_NO_ACCESS; +#endif + + assert(host_priv == &realhost); + host_lock(host_priv); for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) { @@ -672,7 +685,7 @@ host_get_exception_ports( kern_return_t host_swap_exception_ports( - host_priv_t host_priv, + host_priv_t host_priv, exception_mask_t exception_mask, ipc_port_t new_port, exception_behavior_t new_behavior, @@ -705,15 +718,19 @@ host_swap_exception_ports( return KERN_INVALID_ARGUMENT; } } - /* Cannot easily check "new_flavor", but that just means that - * the flavor in the generated exception message might be garbage: - * GIGO */ - host_lock(host_priv); + if (new_flavor != 0 && !VALID_THREAD_STATE_FLAVOR(new_flavor)) + return (KERN_INVALID_ARGUMENT); - count = 0; +#if CONFIG_MACF + if (mac_task_check_set_host_exception_ports(current_task(), exception_mask) != 0) + return KERN_NO_ACCESS; +#endif /* CONFIG_MACF */ - for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) { + host_lock(host_priv); + + assert(EXC_TYPES_COUNT > FIRST_EXCEPTION); + for (count=0, i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT && count < *CountCnt; i++) { if (exception_mask & (1 << i)) { for (j = 0; j < count; j++) { /* @@ -741,9 +758,6 @@ host_swap_exception_ports( ipc_port_copy_send(new_port); host_priv->exc_actions[i].behavior = new_behavior; host_priv->exc_actions[i].flavor = new_flavor; - if (count > *CountCnt) { - break; - } } else old_port[i] = IP_NULL; }/* for */ @@ -752,9 +766,11 @@ host_swap_exception_ports( /* * Consume send rights without any lock held. */ - for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) + while (--i >= FIRST_EXCEPTION) { if (IP_VALID(old_port[i])) ipc_port_release_send(old_port[i]); + } + if (IP_VALID(new_port)) /* consume send right */ ipc_port_release_send(new_port); *CountCnt = count;