diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-10-01 17:35:01 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-10-01 19:33:20 +0200 |
commit | b63dea5ca946c3956637a7bf85a1002866b20cd6 (patch) | |
tree | 682eb89c30f95c85a4a2b158fcdfa867c2fa56c8 | |
parent | 126c0364bf7d72d4f2ecf1ad2f4ebe1d2667940d (diff) | |
download | gnumach-b63dea5ca946c3956637a7bf85a1002866b20cd6.tar.gz gnumach-b63dea5ca946c3956637a7bf85a1002866b20cd6.tar.bz2 gnumach-b63dea5ca946c3956637a7bf85a1002866b20cd6.zip |
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.
-rw-r--r-- | i386/i386/locore.S | 1 | ||||
-rw-r--r-- | i386/i386/locore.h | 2 | ||||
-rw-r--r-- | ipc/ipc_kmsg.c | 2 | ||||
-rw-r--r-- | ipc/mach_msg.c | 2 | ||||
-rw-r--r-- | 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; } |