diff options
-rw-r--r-- | debian/patches/protected_payload.patch | 318 | ||||
-rw-r--r-- | debian/patches/series | 1 |
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 |