]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ipc/ipc_object.c
xnu-4903.221.2.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_object.c
index 49b7e46900197739ac9622f3be86d32a87cd6566..6b40e4761b0b27efe525053ce0918c101d7cfc73 100644 (file)
@@ -70,8 +70,6 @@
  *     Functions to manipulate IPC objects.
  */
 
-#include <mach_rt.h>
-
 #include <mach/mach_types.h>
 #include <mach/boolean.h>
 #include <mach/kern_return.h>
@@ -134,10 +132,9 @@ ipc_object_release(
  *     Returns:
  *             KERN_SUCCESS            Object returned locked.
  *             KERN_INVALID_TASK       The space is dead.
- *             KERN_INVALID_NAME       The name doesn't denote a right.
- *             KERN_INVALID_RIGHT      Name doesn't denote the correct right.
+ *             KERN_INVALID_NAME       The name doesn't denote a right
+ *             KERN_INVALID_RIGHT      Name doesn't denote the correct right
  */
-
 kern_return_t
 ipc_object_translate(
        ipc_space_t             space,
@@ -205,11 +202,13 @@ ipc_object_translate_two(
 
        if ((entry1->ie_bits & MACH_PORT_TYPE(right1)) == MACH_PORT_TYPE_NONE) {
                is_read_unlock(space);
+               mach_port_guard_exception(name1, 0, 0, kGUARD_EXC_INVALID_RIGHT);
                return KERN_INVALID_RIGHT;
        }
 
        if ((entry2->ie_bits & MACH_PORT_TYPE(right2)) == MACH_PORT_TYPE_NONE) {
                is_read_unlock(space);
+               mach_port_guard_exception(name2, 0, 0, kGUARD_EXC_INVALID_RIGHT);
                return KERN_INVALID_RIGHT;
        }
 
@@ -501,15 +500,7 @@ ipc_object_copyin(
        ipc_port_t soright;
        ipc_port_t release_port;
        kern_return_t kr;
-       queue_head_t links_data;
-       queue_t links = &links_data;
-       wait_queue_link_t wql;
-
-#if IMPORTANCE_INHERITANCE
        int assertcnt = 0;
-#endif
-
-       queue_init(links);
 
        /*
         *      Could first try a read lock when doing
@@ -527,19 +518,11 @@ ipc_object_copyin(
                              msgt_name, TRUE,
                              objectp, &soright,
                              &release_port,
-#if IMPORTANCE_INHERITANCE
-                             &assertcnt,
-#endif /* IMPORTANCE_INHERITANCE */
-                             links);
+                             &assertcnt);
        if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
                ipc_entry_dealloc(space, name, entry);
        is_write_unlock(space);
 
-       while(!queue_empty(links)) {
-               wql = (wait_queue_link_t) dequeue(links);
-               wait_queue_link_free(wql);
-       }
-
 #if IMPORTANCE_INHERITANCE
        if (0 < assertcnt && ipc_importance_task_is_any_receiver_type(current_task()->task_imp_base)) {
                ipc_importance_task_drop_internal_assertion(current_task()->task_imp_base, assertcnt);
@@ -595,6 +578,7 @@ ipc_object_copyin_from_kernel(
                ipc_port_t port = (ipc_port_t) object;
 
                ip_lock(port);
+               imq_lock(&port->ip_messages);
                assert(ip_active(port));
                if (port->ip_destination != IP_NULL) {
                        assert(port->ip_receiver == ipc_space_kernel);
@@ -605,6 +589,7 @@ ipc_object_copyin_from_kernel(
                        port->ip_receiver_name = MACH_PORT_NULL;
                        port->ip_destination = IP_NULL;
                }
+               imq_unlock(&port->ip_messages);
                ip_unlock(port);
                break;
            }
@@ -628,7 +613,8 @@ ipc_object_copyin_from_kernel(
                ip_lock(port);
                if (ip_active(port)) {
                        assert(port->ip_receiver_name != MACH_PORT_NULL);
-                       assert(port->ip_receiver == ipc_space_kernel);
+                       assert((port->ip_receiver == ipc_space_kernel) ||
+                   (port->ip_receiver->is_node_id != HOST_LOCAL_NODE));
                        port->ip_mscount++;
                }
 
@@ -766,6 +752,7 @@ ipc_object_copyout(
        boolean_t               overflow,
        mach_port_name_t        *namep)
 {
+       struct knote *kn = current_thread()->ith_knote;
        mach_port_name_t name;
        ipc_entry_t entry;
        kern_return_t kr;
@@ -773,6 +760,11 @@ ipc_object_copyout(
        assert(IO_VALID(object));
        assert(io_otype(object) == IOT_PORT);
 
+       if (ITH_KNOTE_VALID(kn, msgt_name)) {
+               filt_machport_turnstile_prepare_lazily(kn,
+                               msgt_name, (ipc_port_t)object);
+       }
+
        is_write_lock(space);
 
        for (;;) {
@@ -860,6 +852,7 @@ ipc_object_copyout_name(
        ipc_entry_t oentry;
        ipc_entry_t entry;
        kern_return_t kr;
+       struct knote *kn = current_thread()->ith_knote;
 
 #if IMPORTANCE_INHERITANCE
        int assertcnt = 0;
@@ -869,6 +862,11 @@ ipc_object_copyout_name(
        assert(IO_VALID(object));
        assert(io_otype(object) == IOT_PORT);
 
+       if (ITH_KNOTE_VALID(kn, msgt_name)) {
+               filt_machport_turnstile_prepare_lazily(kn,
+                               msgt_name, (ipc_port_t)object);
+       }
+
        kr = ipc_entry_alloc_name(space, name, &entry);
        if (kr != KERN_SUCCESS)
                return kr;
@@ -925,6 +923,8 @@ ipc_object_copyout_name(
                        if (ipc_importance_task_is_any_receiver_type(task_imp)) {
                                assertcnt = port->ip_impcount;
                                ipc_importance_task_reference(task_imp);
+                       } else {
+                               task_imp = IIT_NULL;
                        }
                }