summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/patches/protected_payload.patch318
-rw-r--r--debian/patches/series1
2 files changed, 319 insertions, 0 deletions
diff --git a/debian/patches/protected_payload.patch b/debian/patches/protected_payload.patch
new file mode 100644
index 0000000..719aaf3
--- /dev/null
+++ b/debian/patches/protected_payload.patch
@@ -0,0 +1,318 @@
+diff --git a/include/mach/mach_port.defs b/include/mach/mach_port.defs
+index e1f45e3..96a5987 100644
+--- a/include/mach/mach_port.defs
++++ b/include/mach/mach_port.defs
+@@ -342,5 +342,19 @@ routine mach_port_create_act(
+ user_rbuf_size : vm_size_t;
+ out new_act : thread_t);
+
++#else /* MIGRATING_THREADS */
++
++skip; /* mach_port_set_rpcinfo */
++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);
+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/ipc/ipc_init.c b/ipc/ipc_init.c
+index debda47..7627b4e 100644
+--- a/ipc/ipc_init.c
++++ b/ipc/ipc_init.c
+@@ -80,7 +80,7 @@ ipc_bootstrap(void)
+ sizeof(struct ipc_tree_entry), 0, NULL, NULL, NULL, 0);
+
+ kmem_cache_init(&ipc_object_caches[IOT_PORT], "ipc_port",
+- sizeof(struct ipc_port), 0, NULL, NULL, NULL, 0);
++ sizeof(struct ipc_port)+4, 0, NULL, NULL, NULL, 0);
+
+ kmem_cache_init(&ipc_object_caches[IOT_PORT_SET], "ipc_pset",
+ sizeof(struct ipc_pset), 0, NULL, NULL, NULL, 0);
+diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
+index 0e43410..aa51100 100644
+--- a/ipc/ipc_kmsg.c
++++ b/ipc/ipc_kmsg.c
+@@ -1802,9 +1802,17 @@ ipc_kmsg_copyout_header(msg, space, notify)
+ } 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 (dest->ip_protected_payload == 0) {
++ 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;
+ }
+@@ -1900,10 +1908,18 @@ ipc_kmsg_copyout_header(msg, space, notify)
+ } 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 (dest->ip_protected_payload == 0) {
++ 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;
+ }
+@@ -1935,9 +1951,18 @@ ipc_kmsg_copyout_header(msg, space, notify)
+ 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 (dest->ip_protected_payload == 0) {
++ 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;
+ }
+@@ -2227,9 +2252,16 @@ ipc_kmsg_copyout_header(msg, space, notify)
+ 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 (dest->ip_protected_payload == 0) {
++ 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..59f5a67 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;
++ port->ip_protected_payload = 0;
+ ip_unlock(port);
+ break;
+ }
+diff --git a/ipc/ipc_port.c b/ipc/ipc_port.c
+index d4ade8e..4051746 100644
+--- a/ipc/ipc_port.c
++++ b/ipc/ipc_port.c
+@@ -425,6 +425,25 @@ ipc_port_set_seqno(port, 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;
++ imq_unlock(mqueue);
++}
++
++
++/*
+ * Routine: ipc_port_clear_receiver
+ * Purpose:
+ * Prepares a receive right for transmission/destruction.
+@@ -493,6 +512,7 @@ ipc_port_init(
+ port->ip_seqno = 0;
+ port->ip_msgcount = 0;
+ port->ip_qlimit = MACH_PORT_QLIMIT_DEFAULT;
++ port->ip_protected_payload = 0;
+
+ ipc_mqueue_init(&port->ip_messages);
+ ipc_thread_queue_init(&port->ip_blocked);
+@@ -615,6 +635,7 @@ ipc_port_destroy(
+ /* make port be in limbo */
+ port->ip_receiver_name = MACH_PORT_NULL;
+ port->ip_destination = IP_NULL;
++ port->ip_protected_payload = 0;
+ ip_unlock(port);
+
+ if (!ipc_port_check_circularity(port, pdrequest)) {
+@@ -1240,6 +1261,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..a1a0943 100644
+--- a/ipc/ipc_port.h
++++ b/ipc/ipc_port.h
+@@ -96,6 +96,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 +263,9 @@ 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_receiver(ipc_port_t);
+
+ extern void
+diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c
+index 41fe3de..1edbb47 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.
++ */
++ port->ip_protected_payload = 0;
+ 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.
++ */
++ port->ip_protected_payload = 0;
++
+ assert((bits & MACH_PORT_TYPE_RECEIVE) == 0);
+
+ if (bits & MACH_PORT_TYPE_SEND) {
+diff --git a/ipc/mach_port.c b/ipc/mach_port.c
+index fbc5e69..d80d526 100644
+--- a/ipc/mach_port.c
++++ b/ipc/mach_port.c
+@@ -1564,3 +1564,40 @@ mach_port_set_syscall_right(task, name)
+ }
+ #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;
++}
diff --git a/debian/patches/series b/debian/patches/series
index 01aef04..38560f9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@
60_bigmem.patch
70_dde.patch
inline_x_server_routines.patch
+protected_payload.patch