diff options
author | Flavio Cruz <flaviocruz@gmail.com> | 2023-02-12 13:11:13 -0500 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-02-12 19:43:00 +0100 |
commit | e09f2d9584375a0d9e06bbcadec1910b042df620 (patch) | |
tree | d777fb64dcaac3893bced15ccfa5d946984a58bb /x86_64 | |
parent | 6a46db9fe035c26ab549bc0b681469fc650141d6 (diff) | |
download | gnumach-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.c | 22 |
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; |