]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ipc/ipc_kmsg.c
xnu-3248.60.10.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_kmsg.c
index 3954e31f3e46b72fddde62357bc63562283cd49f..5d78a18486dbb4e032c903d46ddde945a803e114 100644 (file)
@@ -1375,6 +1375,7 @@ ipc_kmsg_send(
        ipc_port_t port;
        thread_t th = current_thread();
        mach_msg_return_t error = MACH_MSG_SUCCESS;
+       boolean_t kernel_reply = FALSE;
        spl_t s;
 
        /* Check if honor qlimit flag is set on thread. */
@@ -1400,6 +1401,8 @@ ipc_kmsg_send(
                return MACH_MSG_SUCCESS;
        }
 
+       ipc_voucher_send_preprocessing(kmsg);
+
        port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
        assert(IP_VALID(port));
        ip_lock(port);
@@ -1445,6 +1448,7 @@ retry:
                assert(IP_VALID(port));
                ip_lock(port);
                /* fall thru with reply - same options */
+               kernel_reply = TRUE;
        }
 
 #if IMPORTANCE_INHERITANCE
@@ -1520,6 +1524,18 @@ retry:
                ipc_kmsg_destroy(kmsg);
                return MACH_MSG_SUCCESS;
        }
+
+       if (error != MACH_MSG_SUCCESS && kernel_reply) {
+               /*
+                * Kernel reply messages that fail can't be allowed to
+                * pseudo-receive on error conditions. We need to just treat
+                * the message as a successful delivery.
+                */
+               ip_release(port); /* JMM - Future: release right, not just ref */
+               kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
+               ipc_kmsg_destroy(kmsg);
+               return MACH_MSG_SUCCESS;
+       }
        return error;
 }
 
@@ -2017,7 +2033,7 @@ ipc_kmsg_copyin_header(
                ipc_port_t dport = (ipc_port_t)dest_port;
 
                /* dport still locked from above */
-               if (ipc_port_importance_delta(dport, 1) == FALSE) {
+               if (ipc_port_importance_delta(dport, IPID_OPTION_SENDPOSSIBLE, 1) == FALSE) {
                        ip_unlock(dport);
                }
        }
@@ -3439,6 +3455,9 @@ ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t *dsc, mach_msg_descrip
        kern_return_t kr;
 
         rcv_addr = 0;
+       if (vm_map_copy_validate_size(map, copy, (vm_map_size_t)size) == FALSE)
+               panic("Inconsistent OOL/copyout size on %p: expected %d, got %lld @%p",
+                     dsc, size, (unsigned long long)copy->size, copy);
         kr = vm_map_copyout(map, &rcv_addr, copy);
         if (kr != KERN_SUCCESS) {
             if (kr == KERN_RESOURCE_SHORTAGE)