From b63dea5ca946c3956637a7bf85a1002866b20cd6 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 1 Oct 2023 17:35:01 +0200 Subject: copyinmsg: Check that we have not overflown This if of course too late in case of a failure, but better assert than get awful bugs, and it's really not supposed to happen. --- i386/i386/locore.S | 1 + i386/i386/locore.h | 2 +- ipc/ipc_kmsg.c | 2 +- ipc/mach_msg.c | 2 +- x86_64/copy_user.c | 3 ++- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/i386/i386/locore.S b/i386/i386/locore.S index d3986793..846f5567 100644 --- a/i386/i386/locore.S +++ b/i386/i386/locore.S @@ -1335,6 +1335,7 @@ copyin_fail: * arg0: user address * arg1: kernel address * arg2: byte count - must be a multiple of four + * arg3: kernel byte count */ ENTRY(copyinmsg) pushl %esi diff --git a/i386/i386/locore.h b/i386/i386/locore.h index 4388ea28..374c8cf9 100644 --- a/i386/i386/locore.h +++ b/i386/i386/locore.h @@ -48,7 +48,7 @@ extern int call_continuation (continuation_t continuation); extern int discover_x86_cpu_type (void); extern int copyin (const void *userbuf, void *kernelbuf, size_t cn); -extern int copyinmsg (const void *userbuf, void *kernelbuf, size_t cn); +extern int copyinmsg (const void *userbuf, void *kernelbuf, size_t cn, size_t kn); extern int copyout (const void *kernelbuf, void *userbuf, size_t cn); extern int copyoutmsg (const void *kernelbuf, void *userbuf, size_t cn); diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c index 105e54d4..33e4d57c 100644 --- a/ipc/ipc_kmsg.c +++ b/ipc/ipc_kmsg.c @@ -505,7 +505,7 @@ ipc_kmsg_get( ikm_init(kmsg, ksize); } - if (copyinmsg(msg, &kmsg->ikm_header, size)) { + if (copyinmsg(msg, &kmsg->ikm_header, size, kmsg->ikm_size)) { ikm_free(kmsg); return MACH_SEND_INVALID_DATA; } diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c index fb6e6dfc..118ce4b3 100644 --- a/ipc/mach_msg.c +++ b/ipc/mach_msg.c @@ -460,7 +460,7 @@ mach_msg_trap( goto slow_get; if (copyinmsg(msg, &kmsg->ikm_header, - send_size)) { + send_size, kmsg->ikm_size)) { ikm_free(kmsg); goto slow_get; } diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c index 178a7545..0d3f301b 100644 --- a/x86_64/copy_user.c +++ b/x86_64/copy_user.c @@ -363,7 +363,7 @@ size_t msg_usize(const mach_msg_header_t *kmsg) * mach_msg_header have the same size in the kernel and user variant (basically * all fields except ports and addresses) */ -int copyinmsg (const void *userbuf, void *kernelbuf, const size_t usize) +int copyinmsg (const void *userbuf, void *kernelbuf, const size_t usize, const size_t ksize) { const mach_msg_user_header_t *umsg = userbuf; mach_msg_header_t *kmsg = kernelbuf; @@ -469,6 +469,7 @@ int copyinmsg (const void *userbuf, void *kernelbuf, const size_t usize) } kmsg->msgh_size = sizeof(mach_msg_header_t) + ksaddr - (vm_offset_t)(kmsg + 1); + assert(kmsg->msgh_size <= ksize); return 0; } -- cgit v1.2.3