diff options
author | Luca Dariz <luca@orpolo.org> | 2023-01-16 11:58:52 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-01-18 02:20:37 +0100 |
commit | 8ddf8e991c0d271d2681627fab08e6730ae73ae0 (patch) | |
tree | 77890e44218b0f75d1067c61f04df8cf6ad189d5 /ipc/ipc_kmsg.c | |
parent | cc05ed085b731232a2436efcaf03aa1e92ad20be (diff) | |
download | gnumach-8ddf8e991c0d271d2681627fab08e6730ae73ae0.tar.gz gnumach-8ddf8e991c0d271d2681627fab08e6730ae73ae0.tar.bz2 gnumach-8ddf8e991c0d271d2681627fab08e6730ae73ae0.zip |
x86_64: expand and shrink messages in copy{in, out}msg routines
* i386/i386/copy_user.h: new file to handle 32/64 bit differences
- add msg_usize() to recontruct the user-space message size
- add copyin/copyout helpers for addresses and ports
* include/mach/message.h: add msg alignment macros
* ipc/ipc_kmsg.c:
- copyin/out ports names instead of using pointer magic
* ipc/ipc_mqueue.c: use msg_usize() to check if we can actually
receive the message
* ipc/mach_msg.c: Likewise for continuations in receive path
* x86_64/Makefrag.am: add x86_64/copy_user.c
* x86_64/copy_user.c: new file to handle message expansion and
shrinking during copyinmsg/copyoutmsg for 64 bit kernels.
- port names -> port pointers on all 64-bit builds
- 32-bit pointer -> 64 bit pointer when using 32-bit userspace
* x86_64/locore.S: remove copyinmsg() and copyoutmsg()
Message-Id: <20230116105857.240210-3-luca@orpolo.org>
Diffstat (limited to 'ipc/ipc_kmsg.c')
-rw-r--r-- | ipc/ipc_kmsg.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c index 55252d46..45070b7a 100644 --- a/ipc/ipc_kmsg.c +++ b/ipc/ipc_kmsg.c @@ -42,6 +42,7 @@ #include <mach/message.h> #include <mach/port.h> #include <machine/locore.h> +#include <machine/copy_user.h> #include <kern/assert.h> #include <kern/kalloc.h> #include <vm/vm_map.h> @@ -68,12 +69,6 @@ #include <ipc/ipc_print.h> #endif -/* msg body is always aligned to 4 bytes */ -typedef uint32_t msg_align_t; - -#define msg_is_misaligned(x) ( ((vm_offset_t)(x)) & (sizeof(msg_align_t)-1) ) -#define msg_align(x) \ - ( ( ((vm_offset_t)(x)) + (sizeof(msg_align_t)-1) ) & ~(sizeof(msg_align_t)-1) ) ipc_kmsg_t ipc_kmsg_cache[NCPUS]; @@ -1388,7 +1383,7 @@ ipc_kmsg_copyin_body( } else { vm_offset_t addr; - if (sizeof(msg_align_t) > sizeof(mach_msg_type_t)) + if (MACH_MSG_ALIGNMENT > sizeof(mach_msg_type_t)) saddr = msg_align(saddr); if ((eaddr - saddr) < sizeof(vm_offset_t)) { @@ -1407,14 +1402,27 @@ ipc_kmsg_copyin_body( if (data == 0) goto invalid_memory; - if (copyinmap(map, (char *) addr, - (char *) data, length) || - (dealloc && - (vm_deallocate(map, addr, length) != - KERN_SUCCESS))) { + if (sizeof(mach_port_name_t) != sizeof(mach_port_t)) + { + mach_port_name_t *src = (mach_port_name_t*)addr; + mach_port_t *dst = (mach_port_t*)data; + for (int i=0; i<number; i++) { + if (copyin_port(src + i, dst + i)) { + kfree(data, length); + goto invalid_memory; + } + } + } else if (copyinmap(map, (char *) addr, + (char *) data, length)) { + kfree(data, length); + goto invalid_memory; + } + if (dealloc && + (vm_deallocate(map, addr, length) != KERN_SUCCESS)) { kfree(data, length); goto invalid_memory; } + } else { vm_map_copy_t copy; @@ -2443,7 +2451,7 @@ ipc_kmsg_copyout_body( } else { vm_offset_t data; - if (sizeof(msg_align_t) > sizeof(mach_msg_type_t)) + if (MACH_MSG_ALIGNMENT > sizeof(mach_msg_type_t)) saddr = msg_align(saddr); data = * (vm_offset_t *) saddr; @@ -2456,8 +2464,17 @@ ipc_kmsg_copyout_body( } else if (is_port) { /* copyout to memory allocated above */ - (void) copyoutmap(map, (char *) data, - (char *) addr, length); + if (sizeof(mach_port_name_t) != sizeof(mach_port_t)) { + mach_port_t *src = (mach_port_t*)data; + mach_port_name_t *dst = (mach_port_name_t*)addr; + for (int i=0; i<number; i++) { + if (copyout_port(src + i, dst + i)) + goto vm_copyout_failure; + } + } else { + (void) copyoutmap(map, (char *) data, + (char *) addr, length); + } kfree(data, length); } else { vm_map_copy_t copy = (vm_map_copy_t) data; |