summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/patches/protected_payload.patch614
1 files changed, 0 insertions, 614 deletions
diff --git a/debian/patches/protected_payload.patch b/debian/patches/protected_payload.patch
index 7c92c7c..2e98a20 100644
--- a/debian/patches/protected_payload.patch
+++ b/debian/patches/protected_payload.patch
@@ -1,111 +1,3 @@
-diff --git a/doc/mach.texi b/doc/mach.texi
-index 49c0d67..351b21c 100644
---- a/doc/mach.texi
-+++ b/doc/mach.texi
-@@ -1330,6 +1330,15 @@ which is conventionally used as a reply port by the recipient of the
- message. The field must carry a send right, a send-once right,
- @code{MACH_PORT_NULL}, or @code{MACH_PORT_DEAD}.
-
-+@item unsigned long msgh_protected_payload
-+The @code{msgh_protected_payload} field carries a payload that is set
-+by the kernel during message delivery. The payload is an opaque
-+identifier that can be used by the receiver to lookup the associated
-+data structure.
-+
-+It is only valid in received messages. See @ref{Message Receive} for
-+further information.
-+
- @item mach_port_seqno_t msgh_seqno
- The @code{msgh_seqno} field provides a sequence number for the message.
- It is only valid in received messages; its value in sent messages is
-@@ -1417,6 +1426,7 @@ types are predefined:
- @item MACH_MSG_TYPE_STRING
- @item MACH_MSG_TYPE_STRING_C
- @item MACH_MSG_TYPE_PORT_NAME
-+@item MACH_MSG_TYPE_PROTECTED_PAYLOAD
- @end table
-
- The following predefined types specify port rights, and receive special
-@@ -1435,6 +1445,11 @@ should be used in preference to @code{MACH_MSG_TYPE_INTEGER_32}.
- @item MACH_MSG_TYPE_MAKE_SEND_ONCE
- @end table
-
-+The type @code{MACH_MSG_TYPE_PROTECTED_PAYLOAD} is used by the kernel
-+to indicate that a delivered message carries a payload in the
-+@code{msgh_protected_payload} field. See @ref{Message Receive} for
-+more information.
-+
- @item msgt_size : 8
- The @code{msgt_size} field specifies the size of each datum, in bits. For
- example, the msgt_size of @code{MACH_MSG_TYPE_INTEGER_32} data is 32.
-@@ -1934,6 +1949,25 @@ loses the receive right after the message was dequeued from it, then
- right still exists, but isn't held by the caller, then
- @code{msgh_local_port} specifies @code{MACH_PORT_NULL}.
-
-+Servers usually associate some state with a receive right. To that
-+end, they might use a hash table to look up the state for the port a
-+message was sent to. To optimize this, a task may associate an opaque
-+@var{payload} with a receive right using the
-+@code{mach_port_set_protected_payload} function. Once this is done,
-+the kernel will set the @code{msgh_protected_payload} field to
-+@var{payload} when delivering a message to this right and indicate
-+this by setting the local part of @code{msgh_bits} to
-+@code{MACH_MSG_TYPE_PROTECTED_PAYLOAD}.
-+
-+The support for protected payloads was added to GNU Mach. To preserve
-+binary compatibility, the @code{msgh_local_port} and
-+@code{msgh_local_port} share the same location. This makes it
-+possible to add the payload information without increasing the size of
-+@code{mach_msg_header_t}. This is an implementation detail. Which
-+field is valid is determined by the local part of the
-+@code{msgh_bits}. Existing software is not affected. When a receive
-+right is transferred to another task, its payload is cleared.
-+
- Received messages are stamped with a sequence number, taken from the
- port from which the message was received. (Messages received from a
- port set are stamped with a sequence number from the appropriate member
-@@ -2715,6 +2749,41 @@ In addition to the normal diagnostic return codes from the call's server
- (normally the kernel), the call may return @code{mach_msg} return codes.
- @end deftypefun
-
-+@deftypefun kern_return_t mach_port_set_protected_payload (@w{ipc_space_t @var{task}}, @w{mach_port_t @var{name}}, @w{unsigned long @var{payload}})
-+The function @code{mach_port_set_protected_payload} sets the protected
-+payload associated with the right @var{name} to @var{payload}.
-+Section @ref{Message Receive} describes how setting a protected
-+payload affects the messages delivered to @var{name}.
-+
-+The function returns @code{KERN_SUCCESS} if the call succeeded,
-+@code{KERN_INVALID_TASK} if @var{task} was invalid,
-+@code{KERN_INVALID_NAME} if @var{name} did not denote a right and
-+@code{KERN_INVALID_RIGHT} if @var{name} denoted a right, but not a
-+receive right.
-+
-+The @code{mach_port_set_protected_payload} call is actually an RPC to
-+@var{task}, normally a send right for a task port, but potentially any
-+send right. In addition to the normal diagnostic return codes from
-+the call's server (normally the kernel), the call may return
-+@code{mach_msg} return codes.
-+@end deftypefun
-+
-+@deftypefun kern_return_t mach_port_clear_protected_payload (@w{ipc_space_t @var{task}}, @w{mach_port_t @var{name}}, @w{unsigned long @var{payload}})
-+The function @code{mach_port_clear_protected_payload} clears the
-+protected payload associated with the right @var{name}.
-+
-+The function returns @code{KERN_SUCCESS} if the call succeeded,
-+@code{KERN_INVALID_TASK} if @var{task} was invalid,
-+@code{KERN_INVALID_NAME} if @var{name} did not denote a right and
-+@code{KERN_INVALID_RIGHT} if @var{name} denoted a right, but not a
-+receive right.
-+
-+The @code{mach_port_clear_protected_payload} call is actually an RPC
-+to @var{task}, normally a send right for a task port, but potentially
-+any send right. In addition to the normal diagnostic return codes
-+from the call's server (normally the kernel), the call may return
-+@code{mach_msg} return codes.
-+@end deftypefun
-
- @node Port Sets
- @subsection Port Sets
diff --git a/include/device/device_types.defs b/include/device/device_types.defs
index ff6cff6..49cc271 100644
--- a/include/device/device_types.defs
@@ -120,32 +12,6 @@ index ff6cff6..49cc271 100644
#ifdef DEVICE_OUTTRAN
outtran: DEVICE_OUTTRAN
#endif
-diff --git a/include/mach/mach_port.defs b/include/mach/mach_port.defs
-index 769d892..c7e8526 100644
---- a/include/mach/mach_port.defs
-+++ b/include/mach/mach_port.defs
-@@ -349,3 +349,21 @@ skip; /* mach_port_create_act */
-
- #endif /* MIGRATING_THREADS */
-
-+/*
-+ * Only valid for receive rights.
-+ * Set the protected payload for this right to the given value.
-+ */
-+
-+routine mach_port_set_protected_payload(
-+ task : ipc_space_t;
-+ name : mach_port_name_t;
-+ payload : natural_t);
-+
-+/*
-+ * Only valid for receive rights.
-+ * Clear the protected payload for this right.
-+ */
-+
-+routine mach_port_clear_protected_payload(
-+ task : ipc_space_t;
-+ name : mach_port_name_t);
diff --git a/include/mach/mach_types.defs b/include/mach/mach_types.defs
index bfce6cb..85ad653 100644
--- a/include/mach/mach_types.defs
@@ -205,33 +71,6 @@ index 1ae36aa..6372ded 100644
#ifdef MEMORY_OBJECT_DESTRUCTOR
destructor: MEMORY_OBJECT_DESTRUCTOR
#endif
-diff --git a/include/mach/message.h b/include/mach/message.h
-index f78e978..0a7297e 100644
---- a/include/mach/message.h
-+++ b/include/mach/message.h
-@@ -136,7 +136,10 @@ typedef struct {
- mach_msg_bits_t msgh_bits;
- mach_msg_size_t msgh_size;
- mach_port_t msgh_remote_port;
-- mach_port_t msgh_local_port;
-+ union {
-+ mach_port_t msgh_local_port;
-+ unsigned long msgh_protected_payload;
-+ };
- mach_port_seqno_t msgh_seqno;
- mach_msg_id_t msgh_id;
- } mach_msg_header_t;
-@@ -253,7 +256,9 @@ typedef struct {
- #define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND
- #define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE
-
--#define MACH_MSG_TYPE_LAST 22 /* Last assigned */
-+#define MACH_MSG_TYPE_PROTECTED_PAYLOAD 23
-+
-+#define MACH_MSG_TYPE_LAST 23 /* Last assigned */
-
- /*
- * A dummy value. Mostly used to indicate that the actual value
diff --git a/include/mach/notify.defs b/include/mach/notify.defs
index 5e59d39..6ba4cde 100644
--- a/include/mach/notify.defs
@@ -246,456 +85,3 @@ index 5e59d39..6ba4cde 100644
#ifdef NOTIFY_OUTTRAN
outtran: NOTIFY_OUTTRAN
#endif
-diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
-index 06cec72..71a0d74 100644
---- a/ipc/ipc_kmsg.c
-+++ b/ipc/ipc_kmsg.c
-@@ -1799,9 +1799,17 @@ ipc_kmsg_copyout_header(
- } else
- ip_unlock(dest);
-
-- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND));
-- msg->msgh_local_port = dest_name;
-+ if (! ipc_port_flag_protected_payload(dest)) {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND));
-+ msg->msgh_local_port = dest_name;
-+ } else {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(
-+ 0, MACH_MSG_TYPE_PROTECTED_PAYLOAD));
-+ msg->msgh_protected_payload =
-+ dest->ip_protected_payload;
-+ }
- msg->msgh_remote_port = MACH_PORT_NULL;
- return MACH_MSG_SUCCESS;
- }
-@@ -1897,10 +1905,18 @@ ipc_kmsg_copyout_header(
- } else
- ip_unlock(dest);
-
-- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-- MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
-- MACH_MSG_TYPE_PORT_SEND));
-- msg->msgh_local_port = dest_name;
-+ if (! ipc_port_flag_protected_payload(dest)) {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
-+ MACH_MSG_TYPE_PORT_SEND));
-+ msg->msgh_local_port = dest_name;
-+ } else {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
-+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
-+ msg->msgh_protected_payload =
-+ dest->ip_protected_payload;
-+ }
- msg->msgh_remote_port = reply_name;
- return MACH_MSG_SUCCESS;
- }
-@@ -1932,9 +1948,18 @@ ipc_kmsg_copyout_header(
- dest_name = MACH_PORT_NULL;
- }
-
-- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE));
-- msg->msgh_local_port = dest_name;
-+ if (! ipc_port_flag_protected_payload(dest)) {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(0,
-+ MACH_MSG_TYPE_PORT_SEND_ONCE));
-+ msg->msgh_local_port = dest_name;
-+ } else {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(0,
-+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
-+ msg->msgh_protected_payload =
-+ dest->ip_protected_payload;
-+ }
- msg->msgh_remote_port = MACH_PORT_NULL;
- return MACH_MSG_SUCCESS;
- }
-@@ -2224,9 +2249,16 @@ ipc_kmsg_copyout_header(
- if (IP_VALID(reply))
- ipc_port_release(reply);
-
-- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-- MACH_MSGH_BITS(reply_type, dest_type));
-- msg->msgh_local_port = dest_name;
-+ if (! ipc_port_flag_protected_payload(dest)) {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(reply_type, dest_type));
-+ msg->msgh_local_port = dest_name;
-+ } else {
-+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
-+ MACH_MSGH_BITS(reply_type,
-+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
-+ msg->msgh_protected_payload = dest->ip_protected_payload;
-+ }
- msg->msgh_remote_port = reply_name;
- }
-
-diff --git a/ipc/ipc_object.c b/ipc/ipc_object.c
-index 982bd4e..db6ef01 100644
---- a/ipc/ipc_object.c
-+++ b/ipc/ipc_object.c
-@@ -481,6 +481,7 @@ ipc_object_copyin_from_kernel(
-
- port->ip_receiver_name = MACH_PORT_NULL;
- port->ip_destination = IP_NULL;
-+ ipc_port_flag_protected_payload_clear(port);
- ip_unlock(port);
- break;
- }
-diff --git a/ipc/ipc_object.h b/ipc/ipc_object.h
-index adf5bca..b83bb5a 100644
---- a/ipc/ipc_object.h
-+++ b/ipc/ipc_object.h
-@@ -57,7 +57,9 @@ typedef struct ipc_object {
- #define IO_VALID(io) (((io) != IO_NULL) && ((io) != IO_DEAD))
-
- #define IO_BITS_KOTYPE 0x0000ffff /* used by the object */
--#define IO_BITS_OTYPE 0x7fff0000 /* determines a cache */
-+#define IO_BITS_OTYPE 0x3fff0000 /* determines a cache */
-+/* The following masks are used to store attributes of ipc ports. */
-+#define IO_BITS_PROTECTED_PAYLOAD 0x40000000 /* pp set? */
- #define IO_BITS_ACTIVE 0x80000000U /* is object alive? */
-
- #define io_active(io) ((int)(io)->io_bits < 0) /* hack */
-diff --git a/ipc/ipc_port.c b/ipc/ipc_port.c
-index 78211e6..89a5d67 100644
---- a/ipc/ipc_port.c
-+++ b/ipc/ipc_port.c
-@@ -423,6 +423,44 @@ ipc_port_set_seqno(
- }
-
- /*
-+ * Routine: ipc_port_set_protected_payload
-+ * Purpose:
-+ * Changes a port's protected payload.
-+ * Conditions:
-+ * The port is locked and active.
-+ */
-+
-+void
-+ipc_port_set_protected_payload(ipc_port_t port, unsigned long payload)
-+{
-+ ipc_mqueue_t mqueue;
-+
-+ mqueue = ipc_port_lock_mqueue(port);
-+ port->ip_protected_payload = payload;
-+ ipc_port_flag_protected_payload_set(port);
-+ imq_unlock(mqueue);
-+}
-+
-+/*
-+ * Routine: ipc_port_clear_protected_payload
-+ * Purpose:
-+ * Clear a port's protected payload.
-+ * Conditions:
-+ * The port is locked and active.
-+ */
-+
-+void
-+ipc_port_clear_protected_payload(ipc_port_t port)
-+{
-+ ipc_mqueue_t mqueue;
-+
-+ mqueue = ipc_port_lock_mqueue(port);
-+ ipc_port_flag_protected_payload_clear(port);
-+ imq_unlock(mqueue);
-+}
-+
-+
-+/*
- * Routine: ipc_port_clear_receiver
- * Purpose:
- * Prepares a receive right for transmission/destruction.
-@@ -491,6 +529,8 @@ ipc_port_init(
- port->ip_seqno = 0;
- port->ip_msgcount = 0;
- port->ip_qlimit = MACH_PORT_QLIMIT_DEFAULT;
-+ ipc_port_flag_protected_payload_clear(port);
-+ port->ip_protected_payload = 0;
-
- ipc_mqueue_init(&port->ip_messages);
- ipc_thread_queue_init(&port->ip_blocked);
-@@ -613,6 +653,7 @@ ipc_port_destroy(
- /* make port be in limbo */
- port->ip_receiver_name = MACH_PORT_NULL;
- port->ip_destination = IP_NULL;
-+ ipc_port_flag_protected_payload_clear(port);
- ip_unlock(port);
-
- if (!ipc_port_check_circularity(port, pdrequest)) {
-@@ -1215,6 +1256,11 @@ ipc_port_print(port)
-
- indent += 2;
-
-+ iprintf("flags ");
-+ printf("has_protected_payload=%d",
-+ ipc_port_flag_protected_payload(port));
-+ printf("\n");
-+
- ipc_object_print(&port->ip_object);
- iprintf("receiver=0x%x", port->ip_receiver);
- printf(", receiver_name=0x%x\n", port->ip_receiver_name);
-@@ -1237,6 +1283,8 @@ ipc_port_print(port)
- printf(", sndrs=0x%x", port->ip_blocked.ithq_base);
- printf(", kobj=0x%x\n", port->ip_kobject);
-
-+ iprintf("protected_payload=%p\n", (void *) port->ip_protected_payload);
-+
- indent -= 2;
- }
-
-diff --git a/ipc/ipc_port.h b/ipc/ipc_port.h
-index 27d2e49..125fefc 100644
---- a/ipc/ipc_port.h
-+++ b/ipc/ipc_port.h
-@@ -48,6 +48,7 @@
- #include <ipc/ipc_mqueue.h>
- #include <ipc/ipc_table.h>
- #include <ipc/ipc_thread.h>
-+#include <ipc/ipc_object.h>
- #include "ipc_target.h"
- #include <mach/rpc.h>
-
-@@ -96,6 +97,7 @@ struct ipc_port {
- mach_port_msgcount_t ip_msgcount;
- mach_port_msgcount_t ip_qlimit;
- struct ipc_thread_queue ip_blocked;
-+ unsigned long ip_protected_payload;
- };
-
- #define ip_object ip_target.ipt_object
-@@ -262,6 +264,12 @@ extern void
- ipc_port_set_seqno(ipc_port_t, mach_port_seqno_t);
-
- extern void
-+ipc_port_set_protected_payload(ipc_port_t, unsigned long);
-+
-+extern void
-+ipc_port_clear_protected_payload(ipc_port_t);
-+
-+extern void
- ipc_port_clear_receiver(ipc_port_t);
-
- extern void
-@@ -325,4 +333,23 @@ ipc_port_dealloc_special(ipc_port_t, ipc_space_t);
- #define ipc_port_release(port) \
- ipc_object_release(&(port)->ip_object)
-
-+extern inline boolean_t
-+ipc_port_flag_protected_payload(const struct ipc_port *port)
-+{
-+ return !! (port->ip_target.ipt_object.io_bits
-+ & IO_BITS_PROTECTED_PAYLOAD);
-+}
-+
-+extern inline void
-+ipc_port_flag_protected_payload_set(struct ipc_port *port)
-+{
-+ port->ip_target.ipt_object.io_bits |= IO_BITS_PROTECTED_PAYLOAD;
-+}
-+
-+extern inline void
-+ipc_port_flag_protected_payload_clear(struct ipc_port *port)
-+{
-+ port->ip_target.ipt_object.io_bits &= ~IO_BITS_PROTECTED_PAYLOAD;
-+}
-+
- #endif /* _IPC_IPC_PORT_H_ */
-diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c
-index 77a68ce..503eb1f 100644
---- a/ipc/ipc_right.c
-+++ b/ipc/ipc_right.c
-@@ -1432,6 +1432,12 @@ ipc_right_copyin(
-
- port->ip_receiver_name = MACH_PORT_NULL;
- port->ip_destination = IP_NULL;
-+
-+ /*
-+ * Clear the protected payload field to retain
-+ * the behavior of mach_msg.
-+ */
-+ ipc_port_flag_protected_payload_clear(port);
- ip_unlock(port);
-
- *objectp = (ipc_object_t) port;
-@@ -1932,6 +1938,12 @@ ipc_right_copyout(
- port->ip_receiver_name = name;
- port->ip_receiver = space;
-
-+ /*
-+ * Clear the protected payload field to retain
-+ * the behavior of mach_msg.
-+ */
-+ ipc_port_flag_protected_payload_clear(port);
-+
- assert((bits & MACH_PORT_TYPE_RECEIVE) == 0);
-
- if (bits & MACH_PORT_TYPE_SEND) {
-diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c
-index 01d974b..1e122c7 100644
---- a/ipc/mach_msg.c
-+++ b/ipc/mach_msg.c
-@@ -1132,11 +1132,19 @@ mach_msg_trap(
- } else
- ip_unlock(dest_port);
-
-- kmsg->ikm_header.msgh_bits =
-- MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
-- MACH_MSG_TYPE_PORT_SEND);
-+ if (! ipc_port_flag_protected_payload(dest_port)) {
-+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
-+ MACH_MSG_TYPE_PORT_SEND_ONCE,
-+ MACH_MSG_TYPE_PORT_SEND);
-+ kmsg->ikm_header.msgh_local_port = dest_name;
-+ } else {
-+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
-+ MACH_MSG_TYPE_PORT_SEND_ONCE,
-+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
-+ kmsg->ikm_header.msgh_protected_payload =
-+ dest_port->ip_protected_payload;
-+ }
- kmsg->ikm_header.msgh_remote_port = reply_name;
-- kmsg->ikm_header.msgh_local_port = dest_name;
- goto fast_put;
-
- abort_request_copyout:
-@@ -1170,11 +1178,19 @@ mach_msg_trap(
- dest_name = MACH_PORT_NULL;
- }
-
-- kmsg->ikm_header.msgh_bits =
-- MACH_MSGH_BITS(0,
-- MACH_MSG_TYPE_PORT_SEND_ONCE);
-+ if (! ipc_port_flag_protected_payload(dest_port)) {
-+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
-+ 0,
-+ MACH_MSG_TYPE_PORT_SEND_ONCE);
-+ kmsg->ikm_header.msgh_local_port = dest_name;
-+ } else {
-+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
-+ 0,
-+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
-+ kmsg->ikm_header.msgh_protected_payload =
-+ dest_port->ip_protected_payload;
-+ }
- kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
-- kmsg->ikm_header.msgh_local_port = dest_name;
- goto fast_put;
- }
-
-@@ -1204,12 +1220,23 @@ mach_msg_trap(
- dest_name = MACH_PORT_NULL;
- }
-
-- kmsg->ikm_header.msgh_bits =
-- MACH_MSGH_BITS_COMPLEX |
-- MACH_MSGH_BITS(0,
-- MACH_MSG_TYPE_PORT_SEND_ONCE);
-+ if (! ipc_port_flag_protected_payload(dest_port)) {
-+ kmsg->ikm_header.msgh_bits =
-+ MACH_MSGH_BITS_COMPLEX
-+ | MACH_MSGH_BITS(
-+ 0,
-+ MACH_MSG_TYPE_PORT_SEND_ONCE);
-+ kmsg->ikm_header.msgh_local_port = dest_name;
-+ } else {
-+ kmsg->ikm_header.msgh_bits =
-+ MACH_MSGH_BITS_COMPLEX
-+ | MACH_MSGH_BITS(
-+ 0,
-+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
-+ kmsg->ikm_header.msgh_protected_payload =
-+ dest_port->ip_protected_payload;
-+ }
- kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
-- kmsg->ikm_header.msgh_local_port = dest_name;
-
- mr = ipc_kmsg_copyout_body(
- (vm_offset_t) (&kmsg->ikm_header + 1),
-diff --git a/ipc/mach_port.c b/ipc/mach_port.c
-index 4a4efcc..4ff39f2 100644
---- a/ipc/mach_port.c
-+++ b/ipc/mach_port.c
-@@ -1564,3 +1564,76 @@ mach_port_set_syscall_right(
- }
- #endif
- #endif /* MIGRATING_THREADS */
-+
-+/*
-+ * Routine: mach_port_set_protected_payload [kernel call]
-+ * Purpose:
-+ * Changes a receive right's protected payload.
-+ * Conditions:
-+ * Nothing locked.
-+ * Returns:
-+ * KERN_SUCCESS Set protected payload.
-+ * KERN_INVALID_TASK The space is null.
-+ * KERN_INVALID_TASK The space is dead.
-+ * KERN_INVALID_NAME The name doesn't denote a right.
-+ * KERN_INVALID_RIGHT Name doesn't denote receive rights.
-+ */
-+
-+kern_return_t
-+mach_port_set_protected_payload(
-+ ipc_space_t space,
-+ mach_port_t name,
-+ unsigned long payload)
-+{
-+ ipc_port_t port;
-+ kern_return_t kr;
-+
-+ if (space == IS_NULL)
-+ return KERN_INVALID_TASK;
-+
-+ kr = ipc_port_translate_receive(space, name, &port);
-+ if (kr != KERN_SUCCESS)
-+ return kr;
-+ /* port is locked and active */
-+
-+ ipc_port_set_protected_payload(port, payload);
-+
-+ ip_unlock(port);
-+ return KERN_SUCCESS;
-+}
-+
-+/*
-+ * Routine: mach_port_clear_protected_payload [kernel call]
-+ * Purpose:
-+ * Clears a receive right's protected payload.
-+ * Conditions:
-+ * Nothing locked.
-+ * Returns:
-+ * KERN_SUCCESS Clear protected payload.
-+ * KERN_INVALID_TASK The space is null.
-+ * KERN_INVALID_TASK The space is dead.
-+ * KERN_INVALID_NAME The name doesn't denote a right.
-+ * KERN_INVALID_RIGHT Name doesn't denote receive rights.
-+ */
-+
-+kern_return_t
-+mach_port_clear_protected_payload(
-+ ipc_space_t space,
-+ mach_port_t name)
-+{
-+ ipc_port_t port;
-+ kern_return_t kr;
-+
-+ if (space == IS_NULL)
-+ return KERN_INVALID_TASK;
-+
-+ kr = ipc_port_translate_receive(space, name, &port);
-+ if (kr != KERN_SUCCESS)
-+ return kr;
-+ /* port is locked and active */
-+
-+ ipc_port_clear_protected_payload(port);
-+
-+ ip_unlock(port);
-+ return KERN_SUCCESS;
-+}