Applied, thanks!
Manolo de Medici, le lun. 06 avril 2026 22:04:52 +0100, a ecrit:
> ipc_kmsg_copyin_body() updated OOL port arrays from 32-bit
> mach_port_name_t elements to 64-bit mach_port_t elements only in the
> non-empty path. For zero-length arrays, the code skipped that
> normalization and left msgtl_size at 32.
>
> On LP64 this causes MIG type checking to reject empty OOL port arrays,
> because the kernel delivers MACH_MSG_TYPE_PORT_SEND with msgtl_size == 32
> instead of 64. Apparently, those kind of messages are never delivered on
> the current Hurd, as such, the bug went unnoticed.
>
> Normalize the descriptor size for OOL port arrays before the length == 0
> branch so empty and non-empty arrays are handled consistently.
> ---
> ipc/ipc_kmsg.c | 59 ++++++++++++++++++++++++++++----------------------
> 1 file changed, 33 insertions(+), 26 deletions(-)
>
> diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
> index 54291a6e..2693db6f 100644
> --- a/ipc/ipc_kmsg.c
> +++ b/ipc/ipc_kmsg.c
> @@ -1392,45 +1392,52 @@ ipc_kmsg_copyin_body(
>
> addr = * (vm_offset_t *) saddr;
>
> - if (length == 0)
> - data = 0;
> - else if (is_port) {
> + if (is_port) {
> const vm_size_t user_length = length;
> +
> /*
> * In 64 bit architectures, out of line port
> names are
> * represented as an array of mach_port_name_t
> which are
> * smaller than mach_port_t.
> */
> if (sizeof(mach_port_name_t) !=
> sizeof(mach_port_t)) {
> + if (longform)
> + type->msgtl_size =
> sizeof(mach_port_t) * 8;
> + else
> + ((mach_msg_type_t
> *)type)->msgt_size = sizeof(mach_port_t) * 8;
> length = sizeof(mach_port_t) * number;
> - type->msgtl_size = sizeof(mach_port_t)
> * 8;
> }
>
> - data = kalloc(length);
> - if (data == 0)
> - goto invalid_memory;
> -
> - if (user_length != length)
> - {
> - 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;
> + if (length == 0) {
> + data = 0;
> + else {
> + data = kalloc(length);
> + if (data == 0)
> + goto invalid_memory;
> +
> + if (user_length != length)
> + {
> + 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,
> user_length) != KERN_SUCCESS)) {
> + 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, user_length) !=
> KERN_SUCCESS)) {
> - kfree(data, length);
> - goto invalid_memory;
> }
> -
> + } else if (length == 0) { /* !is_port */
> + data = 0;
> } else {
> vm_map_copy_t copy;
>
> --
> 2.53.0
>
>
--
Samuel
<c> hiri, le cri ici, c des marrants
<c> j'ai un rep ".uglyhackdirectorywithoutacls" ds mon home
-+- #ens-mim en stage -+-