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/mach_msg.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/mach_msg.c')
-rw-r--r-- | ipc/mach_msg.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c index fe0c43e..371d725 100644 --- a/ipc/mach_msg.c +++ b/ipc/mach_msg.c @@ -954,6 +954,7 @@ mach_msg_trap( (ipc_port_t) kmsg->ikm_header.msgh_local_port; mach_port_t dest_name, reply_name; unsigned long payload; + int have_payload; /* receiving a request message */ @@ -1018,6 +1019,8 @@ mach_msg_trap( else dest_name = MACH_PORT_NULL; payload = dest_port->ip_protected_payload; + have_payload = + ipc_port_flag_protected_payload(dest_port); if ((--dest_port->ip_srights == 0) && (dest_port->ip_nsrequest != IP_NULL)) { @@ -1035,7 +1038,7 @@ mach_msg_trap( } else ip_unlock(dest_port); - if (! ipc_port_flag_protected_payload(dest_port)) { + if (! have_payload) { kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS( MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); @@ -1059,6 +1062,7 @@ mach_msg_trap( 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 */ @@ -1071,6 +1075,8 @@ mach_msg_trap( assert(dest_port->ip_sorights > 0); payload = dest_port->ip_protected_payload; + have_payload = + ipc_port_flag_protected_payload(dest_port); if (dest_port->ip_receiver == space) { ip_release(dest_port); @@ -1084,7 +1090,7 @@ mach_msg_trap( dest_name = MACH_PORT_NULL; } - if (! ipc_port_flag_protected_payload(dest_port)) { + if (! have_payload) { kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS( 0, MACH_MSG_TYPE_PORT_SEND_ONCE); @@ -1104,6 +1110,7 @@ mach_msg_trap( MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): { mach_port_t dest_name; unsigned long payload; + int have_payload; /* receiving a complex reply message */ @@ -1116,6 +1123,9 @@ mach_msg_trap( assert(dest_port->ip_sorights > 0); payload = dest_port->ip_protected_payload; + have_payload = + ipc_port_flag_protected_payload(dest_port); + if (dest_port->ip_receiver == space) { ip_release(dest_port); @@ -1129,7 +1139,7 @@ mach_msg_trap( dest_name = MACH_PORT_NULL; } - if (! ipc_port_flag_protected_payload(dest_port)) { + if (! have_payload) { kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS( |