bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/8] ipc: add protected payload


From: Justus Winter
Subject: [PATCH 1/8] ipc: add protected payload
Date: Thu, 18 Sep 2014 15:22:43 +0200

Add a field ip_protected_payload and a flag ip_has_protected_payload
to struct ipc_port.

Clear the protected payload when a receive port is moved from one ipc
space to another.  This is done to retain the old behavior of
mach_msg, so that a port name is sent in the msgh_local_port field.
If the new owner of that receive right wishes to use the protected
payload mechanism, it has to be explicitly set again.

* ipc/ipc_port.h (struct ipc_port): Add field ip_protected_payload.
(ipc_port_set_protected_payload): Add function declaration.
(ipc_port_clear_protected_payload): Likewise.
(ipc_port_flag_protected_payload): Add accessor for the protected
payload flag.
(ipc_port_flag_protected_payload_set): Likewise.
(ipc_port_flag_protected_payload_clear): Likewise.
* ipc/ipc_port.c (ipc_port_init): Initialize protected payload.
(ipc_port_print): Print protected_payload.
(ipc_port_set_protected_payload): New function.
(ipc_port_clear_protected_payload): Likewise.
(ipc_port_destroy): Clear the payload when moving a receive port.
* ipc/ipc_right.c (ipc_right_copyin): Likewise.
(ipc_right_copyout): Likewise.
* ipc/ipc_object.c (ipc_object_copyin_from_kernel): Likewise.
* ipc/ipc_object.h (IO_BITS_PROTECTED_PAYLOAD): New bitmask.
(IO_BITS_OTYPE): Adjust accordingly.
---
 ipc/ipc_object.c |  1 +
 ipc/ipc_object.h |  4 +++-
 ipc/ipc_port.c   | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 ipc/ipc_port.h   | 27 +++++++++++++++++++++++++++
 ipc/ipc_right.c  | 12 ++++++++++++
 5 files changed, 91 insertions(+), 1 deletion(-)

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) {
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]