bug-hurd
[Top][All Lists]
Advanced

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

[PATCH gnumach] Make mach_msg_header_t have the same size for both 64 bi


From: Flavio Cruz
Subject: [PATCH gnumach] Make mach_msg_header_t have the same size for both 64 bit kernel and userland.
Date: Sun, 12 Feb 2023 18:54:58 -0500

This has several advantages:
1) We don't need to resize mach_msg_header_t, it is just a copy.
2) Mig won't require any changes because it statically computes the size
   of mach_msg_header_t, otherwise we would need two sizes (28 vs 32 bytes).
---
 include/mach/message.h | 15 +++++++++++++--
 x86_64/copy_user.c     | 35 +++++++++++++----------------------
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/include/mach/message.h b/include/mach/message.h
index 63341e6f..eb3b34c0 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -139,7 +139,15 @@ typedef integer_t mach_msg_id_t;
 typedef        struct mach_msg_header {
     mach_msg_bits_t    msgh_bits;
     mach_msg_size_t    msgh_size;
-    mach_port_t                msgh_remote_port;
+    union {
+        mach_port_t            msgh_remote_port;
+        /*
+         * Ensure msgh_remote_port is wide enough to hold a kernel pointer
+         * to avoid message resizing for the 64 bits case. This field should
+         * not be used since it is here just for padding purposes.
+         */
+        rpc_uintptr_t   msgh_remote_port_do_not_use;
+    };
     union {
         mach_port_t    msgh_local_port;
         rpc_uintptr_t  msgh_protected_payload;
@@ -153,7 +161,10 @@ typedef    struct mach_msg_header {
 typedef        struct {
     mach_msg_bits_t    msgh_bits;
     mach_msg_size_t    msgh_size;
-    mach_port_name_t   msgh_remote_port;
+    union {
+        mach_port_name_t       msgh_remote_port;
+        rpc_uintptr_t       msgh_remote_port_do_not_use;
+    };
     union {
         mach_port_name_t       msgh_local_port;
         rpc_uintptr_t msgh_protected_payload;
diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c
index ae062645..dd9fe2d7 100644
--- a/x86_64/copy_user.c
+++ b/x86_64/copy_user.c
@@ -177,29 +177,24 @@ int copyinmsg (const void *userbuf, void *kernelbuf, 
const size_t usize)
   const mach_msg_user_header_t *umsg = userbuf;
   mach_msg_header_t *kmsg = kernelbuf;
 
+#ifdef USER32
   if (copyin(&umsg->msgh_bits, &kmsg->msgh_bits, sizeof(kmsg->msgh_bits)))
     return 1;
   /* kmsg->msgh_size is filled in later */
   if (copyin_port(&umsg->msgh_remote_port, &kmsg->msgh_remote_port))
     return 1;
-#ifdef USER32
-  /* This could contain a payload, but for 32 bits it will be the same size as 
a mach_port_name_t */
-  _Static_assert(sizeof(rpc_uintptr_t) == sizeof(mach_port_name_t),
-                 "rpc_uintptr_t and mach_port_name_t expected to have the same 
size");
   if (copyin_port(&umsg->msgh_local_port, &kmsg->msgh_local_port))
     return 1;
-#else
-  /* For pure 64 bits, the protected payload is as large as a port pointer. */
-  _Static_assert(sizeof(rpc_uintptr_t) == sizeof(mach_port_t),
-                 "rpc_uintptr_t and mach_port_t expected to have the same 
size");
-  if (copyin((char*)umsg + offsetof(mach_msg_user_header_t, msgh_local_port),
-              (char*)kmsg + offsetof(mach_msg_header_t, msgh_local_port),
-             sizeof(rpc_uintptr_t)))
-    return 1;
-#endif
   if (copyin(&umsg->msgh_seqno, &kmsg->msgh_seqno,
              sizeof(kmsg->msgh_seqno) + sizeof(kmsg->msgh_id)))
     return 1;
+#else
+  /* The 64 bit interface ensures the header is the same size, so it does not 
need any resizing. */
+  _Static_assert(sizeof(mach_msg_header_t) == sizeof(mach_msg_user_header_t),
+                "mach_msg_header_t and mach_msg_user_header_t expected to be 
of the same size");
+  if (copyin(&umsg, &kmsg, sizeof(mach_msg_header_t)))
+    return 1;
+#endif
 
   vm_offset_t usaddr, ueaddr, ksaddr;
   ksaddr = (vm_offset_t)(kmsg + 1);
@@ -283,25 +278,21 @@ int copyoutmsg (const void *kernelbuf, void *userbuf, 
const size_t ksize)
 {
   const mach_msg_header_t *kmsg = kernelbuf;
   mach_msg_user_header_t *umsg = userbuf;
-
+#ifdef USER32
   if (copyout(&kmsg->msgh_bits, &umsg->msgh_bits, sizeof(kmsg->msgh_bits)))
     return 1;
   /* umsg->msgh_size is filled in later */
   if (copyout_port(&kmsg->msgh_remote_port, &umsg->msgh_remote_port))
     return 1;
-#ifdef USER32
   if (copyout_port(&kmsg->msgh_local_port, &umsg->msgh_local_port))
     return 1;
-#else
-  /* Handle protected payloads correctly, same as copyinmsg. */
-  if (copyout((char*)kmsg + offsetof(mach_msg_header_t, msgh_local_port),
-              (char*)umsg + offsetof(mach_msg_user_header_t, msgh_local_port),
-             sizeof(rpc_uintptr_t)))
-    return 1;
-#endif
   if (copyout(&kmsg->msgh_seqno, &umsg->msgh_seqno,
              sizeof(kmsg->msgh_seqno) + sizeof(kmsg->msgh_id)))
     return 1;
+#else
+  if (copyout(&kmsg, &umsg, sizeof(mach_msg_header_t)))
+    return 1;
+#endif  /* USER32 */
 
   vm_offset_t ksaddr, keaddr, usaddr;
   ksaddr = (vm_offset_t)(kmsg + 1);
-- 
2.39.1




reply via email to

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