diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-08-18 11:32:15 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-08-20 18:59:44 +0200 |
commit | 803f226e749138713b5c767b1a108544ce5e0baf (patch) | |
tree | 1871c1ae3c86bc896a3cae7880403feb7ea04bc0 /ipc/ipc_kmsg.c | |
parent | 85ec6f573feb5f2564e1b1ce0064f829c9790d6f (diff) |
ipc: fix locking issues
* ipc/ipc_port.h (struct ipc_port): Document locking exception.
* ipc/ipc_port.c (ipc_port_destroy): Avoid accessing `port's fields
without the lock.
(ipc_port_alloc_special): Lock `port'.
* ipc/mach_msg.c (mach_msg_trap): Avoid using
`ipc_port_flag_protected_payload' on unlocked port.
* ipc/ipc_kmsg.c (ipc_kmsg_copyout_header): Likewise.
Diffstat (limited to 'ipc/ipc_kmsg.c')
-rw-r--r-- | ipc/ipc_kmsg.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c index 5076809..6c4b59a 100644 --- a/ipc/ipc_kmsg.c +++ b/ipc/ipc_kmsg.c @@ -1713,6 +1713,7 @@ ipc_kmsg_copyout_header( mach_port_t dest_name; ipc_port_t nsrequest; unsigned long payload; + int have_payload; /* receiving an asynchronous message */ @@ -1732,6 +1733,7 @@ ipc_kmsg_copyout_header( else dest_name = MACH_PORT_NULL; payload = dest->ip_protected_payload; + have_payload = ipc_port_flag_protected_payload(dest); if ((--dest->ip_srights == 0) && ((nsrequest = dest->ip_nsrequest) != IP_NULL)) { @@ -1745,7 +1747,7 @@ ipc_kmsg_copyout_header( } else ip_unlock(dest); - if (! ipc_port_flag_protected_payload(dest)) { + if (! have_payload) { msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND)); msg->msgh_local_port = dest_name; @@ -1766,6 +1768,7 @@ ipc_kmsg_copyout_header( mach_port_t dest_name, reply_name; ipc_port_t nsrequest; unsigned long payload; + int have_payload; /* receiving a request message */ @@ -1837,6 +1840,7 @@ ipc_kmsg_copyout_header( else dest_name = MACH_PORT_NULL; payload = dest->ip_protected_payload; + have_payload = ipc_port_flag_protected_payload(dest); if ((--dest->ip_srights == 0) && ((nsrequest = dest->ip_nsrequest) != IP_NULL)) { @@ -1850,7 +1854,7 @@ ipc_kmsg_copyout_header( } else ip_unlock(dest); - if (! ipc_port_flag_protected_payload(dest)) { + if (! have_payload) { msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND)); @@ -1868,6 +1872,7 @@ ipc_kmsg_copyout_header( case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): { mach_port_t dest_name; unsigned long payload; + int have_payload; /* receiving a reply message */ @@ -1882,6 +1887,7 @@ ipc_kmsg_copyout_header( assert(dest->ip_sorights > 0); payload = dest->ip_protected_payload; + have_payload = ipc_port_flag_protected_payload(dest); if (dest->ip_receiver == space) { ip_release(dest); @@ -1895,7 +1901,7 @@ ipc_kmsg_copyout_header( dest_name = MACH_PORT_NULL; } - if (! ipc_port_flag_protected_payload(dest)) { + if (! have_payload) { msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE)); @@ -1922,6 +1928,7 @@ ipc_kmsg_copyout_header( ipc_port_t reply = (ipc_port_t) msg->msgh_local_port; mach_port_t dest_name, reply_name; unsigned long payload; + int have_payload; if (IP_VALID(reply)) { ipc_port_t notify_port; @@ -2161,6 +2168,7 @@ ipc_kmsg_copyout_header( copyout_dest: payload = dest->ip_protected_payload; + have_payload = ipc_port_flag_protected_payload(dest); if (ip_active(dest)) { ipc_object_copyout_dest(space, (ipc_object_t) dest, @@ -2189,7 +2197,7 @@ ipc_kmsg_copyout_header( if (IP_VALID(reply)) ipc_port_release(reply); - if (! ipc_port_flag_protected_payload(dest)) { + if (! have_payload) { msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | MACH_MSGH_BITS(reply_type, dest_type)); msg->msgh_local_port = dest_name; |