aboutsummaryrefslogtreecommitdiff
path: root/x86_64
diff options
context:
space:
mode:
authorFlavio Cruz <flaviocruz@gmail.com>2023-02-12 13:11:13 -0500
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-02-12 19:43:00 +0100
commite09f2d9584375a0d9e06bbcadec1910b042df620 (patch)
treed777fb64dcaac3893bced15ccfa5d946984a58bb /x86_64
parent6a46db9fe035c26ab549bc0b681469fc650141d6 (diff)
downloadgnumach-e09f2d9584375a0d9e06bbcadec1910b042df620.tar.gz
gnumach-e09f2d9584375a0d9e06bbcadec1910b042df620.tar.bz2
gnumach-e09f2d9584375a0d9e06bbcadec1910b042df620.zip
Consider protected payloads in mach_msg_header_t when resizing messages.
Protected payloads will be 8-byte longs which are the same size as kernel ports. Also aligned all the structures to be 4-byte aligned since it makes it easier to parse them as padding won't be added to mach_msg_user_header_t before the protected payload. Message-Id: <Y+krwRFIUeyRszl9@jupiter.tail36e24.ts.net>
Diffstat (limited to 'x86_64')
-rw-r--r--x86_64/copy_user.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c
index b340d6f0..ae062645 100644
--- a/x86_64/copy_user.c
+++ b/x86_64/copy_user.c
@@ -16,6 +16,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <stddef.h>
#include <string.h>
#include <kern/debug.h>
@@ -181,8 +182,21 @@ int copyinmsg (const void *userbuf, void *kernelbuf, const size_t usize)
/* 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;
@@ -275,8 +289,16 @@ int copyoutmsg (const void *kernelbuf, void *userbuf, const size_t ksize)
/* 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;