Re: [PATCH] elf-load: Respect PT_GNU_STACK

2024-03-27 Thread Sergey Bugaev
On Wed, Mar 27, 2024 at 9:37 PM Samuel Thibault  wrote:
> But it's not getting used anywhere?

Indeed, I forgot to extract the kern/bootstrap.c part of the change.
Ooops :) Thanks for pointing it out.

Sergey

-- >8 --

If a bootstrap ELF contains a PT_GNU_STACK phdr, take stack protection
from there.  Otherwise, default to VM_PROT_ALL.
---
 include/mach/exec/elf.h  | 1 +
 include/mach/exec/exec.h | 2 ++
 kern/bootstrap.c | 8 
 kern/elf-load.c  | 7 +++
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/mach/exec/elf.h b/include/mach/exec/elf.h
index 9e4f8f7e..55304496 100644
--- a/include/mach/exec/elf.h
+++ b/include/mach/exec/elf.h
@@ -300,6 +300,7 @@ typedef struct {
 #define PT_NOTE4
 #define PT_SHLIB   5
 #define PT_PHDR6
+#define PT_GNU_STACK   0x6474e551
 
 #define PT_LOPROC  0x7000
 #define PT_HIPROC  0x7fff
diff --git a/include/mach/exec/exec.h b/include/mach/exec/exec.h
index 94b234b0..29fa897d 100644
--- a/include/mach/exec/exec.h
+++ b/include/mach/exec/exec.h
@@ -51,6 +51,8 @@ typedef struct exec_info
/* (ELF) Address of interpreter string for loading shared libraries, 
null if none.  */
vm_offset_t interp;
 
+   /* Required stack protection.  */
+   vm_prot_t stack_prot;
 } exec_info_t;
 
 typedef int exec_sectype_t;
diff --git a/kern/bootstrap.c b/kern/bootstrap.c
index 49358ac6..0470e1b6 100644
--- a/kern/bootstrap.c
+++ b/kern/bootstrap.c
@@ -620,10 +620,10 @@ build_args_and_stack(struct exec_info *boot_exec_info,
stack_size = round_page(STACK_SIZE);
stack_base = user_stack_low(stack_size);
 
-   (void) vm_allocate(current_task()->map,
-   &stack_base,
-   stack_size,
-   FALSE);
+   (void) vm_map(current_map(), &stack_base, stack_size,
+ 0, FALSE, IP_NULL, 0, FALSE,
+ boot_exec_info->stack_prot, VM_PROT_ALL,
+ VM_INHERIT_DEFAULT);
 
arg_pos = (char *)
set_user_regs(stack_base, stack_size, boot_exec_info, arg_len);
diff --git a/kern/elf-load.c b/kern/elf-load.c
index ce86327c..596233a8 100644
--- a/kern/elf-load.c
+++ b/kern/elf-load.c
@@ -73,6 +73,8 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t 
*read_exec,
if (actual < phsize)
return EX_CORRUPT;
 
+   out_info->stack_prot = VM_PROT_ALL;
+
for (i = 0; i < x.e_phnum; i++)
{
ph = (Elf_Phdr *)((vm_offset_t)phdr + i * x.e_phentsize);
@@ -89,6 +91,11 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t 
*read_exec,
  ph->p_vaddr + loadbase, 
ph->p_memsz, type);
if (result)
return result;
+   } else if (ph->p_type == PT_GNU_STACK) {
+   out_info->stack_prot = 0;
+   if (ph->p_flags & PF_R) out_info->stack_prot |= 
VM_PROT_READ;
+   if (ph->p_flags & PF_W) out_info->stack_prot |= 
VM_PROT_WRITE;
+   if (ph->p_flags & PF_X) out_info->stack_prot |= 
VM_PROT_EXECUTE;
}
}
 
-- 
2.44.0




Re: [PATCH 17/17] tests: Create tests/ in the build tree before trying to use it

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:41 +0300, a ecrit:
> ---
>  tests/user-qemu.mk | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/tests/user-qemu.mk b/tests/user-qemu.mk
> index fd5ae1ab..4f8390b6 100644
> --- a/tests/user-qemu.mk
> +++ b/tests/user-qemu.mk
> @@ -130,6 +130,7 @@ SRC_TESTLIB= \
>   $(MIG_GEN_CC)
>  
>  tests/errlist.c: $(addprefix $(srcdir)/include/mach/,message.h kern_return.h 
> mig_errors.h)
> + mkdir -p tests
>   echo "/* autogenerated file */" >$@
>   echo "#include " >>$@
>   echo "#include " >>$@
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 16/17] tests: Don't ask for executable stack

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:40 +0300, a ecrit:
> ---
>  tests/start.S| 2 ++
>  tests/syscalls.S | 2 ++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/tests/start.S b/tests/start.S
> index b795bfbd..15970fb9 100644
> --- a/tests/start.S
> +++ b/tests/start.S
> @@ -26,3 +26,5 @@ _start:
>  movq%rsp,%rdi
>  callq   c_start
>  #endif /* __x86_64__ */
> +
> + .section .note.GNU-stack,"",%progbits
> diff --git a/tests/syscalls.S b/tests/syscalls.S
> index df9c9bc0..b1e18aa8 100644
> --- a/tests/syscalls.S
> +++ b/tests/syscalls.S
> @@ -2,3 +2,5 @@
>  #include 
>  
>  kernel_trap(invalid_syscall,-31,0)
> +
> + .section .note.GNU-stack,"",%progbits
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 15/17] tests: Make exception subcode a long

2024-03-27 Thread Samuel Thibault
Applied, thansks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:39 +0300, a ecrit:
> ---
>  tests/test-syscalls.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c
> index 63c2690a..fbfecd9c 100644
> --- a/tests/test-syscalls.c
> +++ b/tests/test-syscalls.c
> @@ -34,7 +34,7 @@ static struct {
>mach_port_t task;
>integer_t exception;
>integer_t code;
> -  integer_t subcode;
> +  long_integer_t subcode;
>  } last_exc;
>  kern_return_t catch_exception_raise(mach_port_t exception_port,
>  mach_port_t thread, mach_port_t task,
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 14/17] tests: Use vm_page_size

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:38 +0300, a ecrit:
> ---
>  tests/testlib_thread_start.c | 19 +++
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/tests/testlib_thread_start.c b/tests/testlib_thread_start.c
> index fa8af0ea..df4b19ab 100644
> --- a/tests/testlib_thread_start.c
> +++ b/tests/testlib_thread_start.c
> @@ -30,30 +30,33 @@
>  #include 
>  #include 
>  
> -/* This is just a temporary mapping to set up the stack */
> -static long stack_top[PAGE_SIZE/sizeof(long)] __attribute__ ((aligned 
> (PAGE_SIZE)));
> -
>  thread_t test_thread_start(task_t task, void(*routine)(void*), void* arg) {
> -  const vm_size_t stack_size = PAGE_SIZE * 16;
> +  const vm_size_t stack_size = vm_page_size * 16;
>kern_return_t ret;
> -  vm_address_t stack;
> +  vm_address_t stack, local_stack;
> +
> +  ret = vm_allocate(mach_task_self(), &local_stack, vm_page_size, TRUE);
> +  ASSERT_RET(ret, "can't allocate local stack");
>  
>ret = vm_allocate(task, &stack, stack_size, TRUE);
>ASSERT_RET(ret, "can't allocate the stack for a new thread");
>  
> -  ret = vm_protect(task, stack, PAGE_SIZE, FALSE, VM_PROT_NONE);
> +  ret = vm_protect(task, stack, vm_page_size, FALSE, VM_PROT_NONE);
>ASSERT_RET(ret, "can't protect the stack from overflows");
>  
> -  long *top = (long*)((vm_offset_t)stack_top + PAGE_SIZE) - 1;
> +  long *top = (long*)(local_stack + vm_page_size) - 1;
>  #ifdef __i386__
>*top = (long)arg; /* The argument is passed on the stack on x86_32 */
>*(top - 1) = 0;   /* The return address */
>  #elif defined(__x86_64__)
>*top = 0; /* The return address */
>  #endif
> -  ret = vm_write(task, stack + stack_size - PAGE_SIZE, 
> (vm_offset_t)stack_top, PAGE_SIZE);
> +  ret = vm_write(task, stack + stack_size - vm_page_size, local_stack, 
> vm_page_size);
>ASSERT_RET(ret, "can't initialize the stack for the new thread");
>  
> +  ret = vm_deallocate(mach_task_self(), local_stack, vm_page_size);
> +  ASSERT_RET(ret, "can't deallocate local stack");
> +
>thread_t thread;
>ret = thread_create(task, &thread);
>ASSERT_RET(ret, "thread_create()");
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 13/17] tests: Add vm_page_size

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:37 +0300, a ecrit:
> ---
>  tests/include/testlib.h |  2 ++
>  tests/testlib.c | 13 +
>  2 files changed, 15 insertions(+)
> 
> diff --git a/tests/include/testlib.h b/tests/include/testlib.h
> index d2367124..035fdc28 100644
> --- a/tests/include/testlib.h
> +++ b/tests/include/testlib.h
> @@ -70,6 +70,8 @@ thread_t test_thread_start(task_t task, 
> void(*routine)(void*), void* arg);
>  mach_port_t host_priv(void);
>  mach_port_t device_priv(void);
>  
> +extern vm_size_t vm_page_size;
> +
>  extern void mach_msg_destroy(mach_msg_header_t *msg);
>  
>  extern mach_msg_return_t mach_msg_server(
> diff --git a/tests/testlib.c b/tests/testlib.c
> index baf1ce5c..12c5e771 100644
> --- a/tests/testlib.c
> +++ b/tests/testlib.c
> @@ -29,6 +29,11 @@
>  #include 
>  #include 
>  
> +#ifdef PAGE_SIZE
> +vm_size_t vm_page_size = PAGE_SIZE;
> +#else
> +vm_size_t vm_page_size;
> +#endif
>  
>  static int argc = 0;
>  static char *argv_unknown[] = {"unknown", "m1", "123", "456"};
> @@ -212,6 +217,7 @@ mach_msg_return_t mach_msg_server_once(
>  void __attribute__((used, retain))
>  c_start(void **argptr)
>  {
> +  kern_return_t kr;
>intptr_t* argcptr = (intptr_t*)argptr;
>argc = argcptr[0];
>argv = (char **) &argcptr[1];
> @@ -224,6 +230,13 @@ c_start(void **argptr)
>mach_atoi(argv[1], &host_priv_port);
>mach_atoi(argv[2], &device_master_port);
>  
> +#ifndef PAGE_SIZE
> +  vm_statistics_data_t stats;
> +  kr = vm_statistics (mach_task_self(), &stats);
> +  ASSERT_RET(kr, "can't get page size");
> +  vm_page_size = stats.pagesize;
> +#endif
> +
>printf("started %s", argv[0]);
>for (int i=1; i{
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 12/17] tests: Add a more serious mach_msg_server() routine

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:36 +0300, a ecrit:
> ---
>  tests/include/testlib.h |  16 ++
>  tests/test-syscalls.c   |  40 +
>  tests/testlib.c | 123 
>  3 files changed, 142 insertions(+), 37 deletions(-)
> 
> diff --git a/tests/include/testlib.h b/tests/include/testlib.h
> index cdb2ce13..d2367124 100644
> --- a/tests/include/testlib.h
> +++ b/tests/include/testlib.h
> @@ -70,6 +70,22 @@ thread_t test_thread_start(task_t task, 
> void(*routine)(void*), void* arg);
>  mach_port_t host_priv(void);
>  mach_port_t device_priv(void);
>  
> +extern void mach_msg_destroy(mach_msg_header_t *msg);
> +
> +extern mach_msg_return_t mach_msg_server(
> + boolean_t   (*demux) (mach_msg_header_t *request,
> +   mach_msg_header_t *reply),
> + mach_msg_size_t max_size,
> + mach_port_t rcv_name,
> + mach_msg_option_t   options);
> +
> +extern mach_msg_return_t mach_msg_server_once(
> + boolean_t   (*demux) (mach_msg_header_t *request,
> +   mach_msg_header_t *reply),
> + mach_msg_size_t max_size,
> + mach_port_t rcv_name,
> + mach_msg_option_t   options);
> +
>  int main(int argc, char *argv[], int envc, char *envp[]);
>  
>  #endif /* TESTLIB_H */
> diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c
> index be4df8c3..63c2690a 100644
> --- a/tests/test-syscalls.c
> +++ b/tests/test-syscalls.c
> @@ -49,44 +49,10 @@ kern_return_t catch_exception_raise(mach_port_t 
> exception_port,
>last_exc.exception = exception;
>last_exc.code = code;
>last_exc.subcode = subcode;
> +  thread_terminate(thread);
>return KERN_SUCCESS;
>  }
>  
> -static char simple_request_data[PAGE_SIZE];
> -static char simple_reply_data[PAGE_SIZE];
> -int simple_msg_server(boolean_t (*demuxer) (mach_msg_header_t *request,
> - mach_msg_header_t *reply),
> -  mach_port_t rcv_port_name,
> -  int num_msgs)
> -{
> -  int midx = 0, mok = 0;
> -  int ret;
> -  mig_reply_header_t *request = (mig_reply_header_t*)simple_request_data;
> -  mig_reply_header_t *reply = (mig_reply_header_t*)simple_reply_data;
> -  while ((midx - num_msgs) < 0)
> -{
> -  ret = mach_msg(&request->Head, MACH_RCV_MSG, 0, PAGE_SIZE,
> - rcv_port_name, 0, MACH_PORT_NULL);
> -  switch (ret)
> -{
> -case MACH_MSG_SUCCESS:
> -  if ((*demuxer)(&request->Head, &reply->Head))
> -mok++;  // TODO send reply
> -  else
> -FAILURE("demuxer didn't handle the message");
> -  break;
> -default:
> -  ASSERT_RET(ret, "receiving in msg_server");
> -  break;
> -}
> -  midx++;
> -}
> -  if (mok != midx)
> -FAILURE("wrong number of message received");
> -  return mok != midx;
> -}
> -
> -
>  void test_syscall_bad_arg_on_stack(void *arg)
>  {
>/* mach_msg() has 7 arguments, so the last one should be always
> @@ -152,13 +118,13 @@ int main(int argc, char *argv[], int envc, char *envp[])
>  
>memset(&last_exc, 0, sizeof(last_exc));
>test_thread_start(mach_task_self(), test_bad_syscall_num, NULL);
> -  ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server");
> +  ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, 
> MACH_MSG_OPTION_NONE), "error in exc server");
>ASSERT((last_exc.exception == EXC_BAD_INSTRUCTION) && (last_exc.code == 
> EXC_I386_INVOP),
>   "bad exception for test_bad_syscall_num()");
>  
>memset(&last_exc, 0, sizeof(last_exc));
>test_thread_start(mach_task_self(), test_syscall_bad_arg_on_stack, NULL);
> -  ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server");
> +  ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, 
> MACH_MSG_OPTION_NONE), "error in exc server");
>ASSERT((last_exc.exception == EXC_BAD_ACCESS) && (last_exc.code == 
> KERN_INVALID_ADDRESS),
>   "bad exception for test_syscall_bad_arg_on_stack()");
>  
> diff --git a/tests/testlib.c b/tests/testlib.c
> index d2198830..baf1ce5c 100644
> --- a/tests/testlib.c
> +++ b/tests/testlib.c
> @@ -26,6 +26,7 @@
>  #include 
>  
>  #include 
> +#include 
>  #include 
>  
>  
> @@ -81,6 +82,128 @@ const char* e2s(int err)
>}
>  }
>  
> +void mach_msg_destroy(mach_msg_header_t *msg)
> +{
> + mach_port_t tmp;
> +
> + tmp = mach_reply_port();
> +
> + msg->msgh_local_port = msg->msgh_remote_port;
> + msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,
> + MACH_MSGH_BITS_REMOTE(msg->msgh_bits))
> +  | MACH_MSGH_BITS_OTHER(msg->msgh_bits);
> +
> + mach_msg(msg, MACH_SEND_MSG, msg->msgh_size, 0, MACH_PORT_NULL,
> +  MACH_MSG_TIMEOUT_NONE, MACH_PORT_NUL

Re: [PATCH 11/17] tests: Fix halt()

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:35 +0300, a ecrit:
> Mark it as noreturn, and make sure to halt, not reboot.
> ---
>  tests/include/testlib.h | 2 +-
>  tests/testlib.c | 3 ++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/include/testlib.h b/tests/include/testlib.h
> index a3f3a6a8..cdb2ce13 100644
> --- a/tests/include/testlib.h
> +++ b/tests/include/testlib.h
> @@ -63,7 +63,7 @@ extern const char* TEST_FAILURE_MARKER;
>  
>  const char* e2s(int err);
>  const char* e2s_gnumach(int err);
> -void halt();
> +extern void __attribute__((noreturn)) halt();
>  int msleep(uint32_t timeout);
>  thread_t test_thread_start(task_t task, void(*routine)(void*), void* arg);
>  
> diff --git a/tests/testlib.c b/tests/testlib.c
> index 2eaeb591..d2198830 100644
> --- a/tests/testlib.c
> +++ b/tests/testlib.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -55,7 +56,7 @@ mach_port_t device_priv(void)
>  
>  void halt()
>  {
> -  int ret = host_reboot(host_priv_port, 0);
> +  int ret = host_reboot(host_priv_port, RB_HALT);
>ASSERT_RET(ret, "host_reboot() failed!");
>while (1)
>  ;
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 10/17] Make -fno-PIE etc. architecture-dependent

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:34 +0300, a ecrit:
> There might be good reasons why Mach on x86 shouldn't be built as PIC/
> PIE, but there are also very good reasons to support PIE on other
> architectures. Potentially implementing KASLR is one such reason; but
> also the Linux AArch64 boot protocol (that the AArch64 port will use for
> booting) lets the bootloader load the kernel image at any address,
> which makes PIC pretty much required.
> ---
>  Makefile.am  | 4 
>  i386/Makefrag.am | 4 
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index ad38249b..357e8470 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -79,10 +79,6 @@ AM_CFLAGS += \
>   -fno-stack-protector
>  endif
>  
> -# We do not support or need position-independent
> -AM_CFLAGS += \
> - -no-pie -fno-PIE -fno-pie -fno-pic
> -
>  # This must be the same size as port names, see e.g. ipc/ipc_entry.c
>  AM_CFLAGS += -DRDXTREE_KEY_32
>  
> diff --git a/i386/Makefrag.am b/i386/Makefrag.am
> index 5e7d4740..7a339417 100644
> --- a/i386/Makefrag.am
> +++ b/i386/Makefrag.am
> @@ -170,6 +170,10 @@ gnumach_LINKFLAGS += \
>   -T '$(srcdir)'/i386/ldscript
>  endif
>  
> +# We do not support or need position-independent
> +AM_CFLAGS += \
> + -no-pie -fno-PIE -fno-pie -fno-pic
> +
>  AM_CFLAGS += \
>   -mno-3dnow \
>   -mno-mmx \
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 09/17] Move copy{in,out}msg declarations to copy_user.h

2024-03-27 Thread Samuel Thibault
Sergey Bugaev, le mer. 27 mars 2024 19:18:33 +0300, a ecrit:
> Since they are implemented in copy_user.c
> ---
>  i386/i386/locore.h |  4 
>  ipc/copy_user.h| 15 +++
>  kern/exception.c   |  1 +
>  3 files changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/i386/i386/locore.h b/i386/i386/locore.h
> index 217e6dec..8ff587ed 100644
> --- a/i386/i386/locore.h
> +++ b/i386/i386/locore.h
> @@ -52,10 +52,6 @@ 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);
>  #ifdef USER32
>  extern int copyoutmsg (const void *kernelbuf, void *userbuf, size_t cn);

Didn't you also want to move this one?

> -#else
> -static inline int copyoutmsg (const void *kernelbuf, void *userbuf, size_t 
> cn) {
> - return copyout (kernelbuf, userbuf, cn);
> -}
>  #endif
>  
>  extern int inst_fetch (int eip, int cs);
> diff --git a/ipc/copy_user.h b/ipc/copy_user.h
> index a57b3ee5..33beacd0 100644
> --- a/ipc/copy_user.h
> +++ b/ipc/copy_user.h
> @@ -25,6 +25,21 @@
>  #include 
>  #include 
>  
> +int copyinmsg(
> + const void  *userbuf,
> + void*kernelbuf,
> + size_t  usize,
> + size_t  ksize);
> +
> +#ifdef USER32
> +int copyoutmsg(
> + const void  *kernelbuf,
> + void*userbuf,
> + size_t  ksize);
> +#else
> +#define copyoutmsg   copyout

Better define with parameters, so that it doesn't catch e.g. variables
called copyoutmsg.

> +#endif
> +
>  /*
>   * The copyin_32to64() and copyout_64to32() routines are meant for data types
>   * that have different size in kernel and user space. They should be 
> independent
> diff --git a/kern/exception.c b/kern/exception.c
> index 7139b466..cc023d45 100644
> --- a/kern/exception.c
> +++ b/kern/exception.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 08/17] ipc: Turn ipc_entry_lookup_failed() into a macro

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:32 +0300, a ecrit:
> ipc_entry_lookup_failed() is used with both mach_msg_user_header_t and
> mach_msg_header_t arguments, which are different types. Make it into a
> macro, so it works with both.
> ---
>  ipc/ipc_space.h | 22 +-
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h
> index 96d58942..9adbd3f7 100644
> --- a/ipc/ipc_space.h
> +++ b/ipc/ipc_space.h
> @@ -159,15 +159,19 @@ ipc_entry_lookup(
>  
>  extern volatile boolean_t mach_port_deallocate_debug;
>  
> -static inline void
> -ipc_entry_lookup_failed(mach_msg_header_t *msg, mach_port_name_t name)
> -{
> - if (name == MACH_PORT_NAME_NULL || name == MACH_PORT_NAME_DEAD)
> - return;
> - printf("task %.*s looked up a bogus port %lu for %d, most probably a 
> bug.\n", (int) sizeof current_task()->name, current_task()->name, (unsigned 
> long) name, msg->msgh_id);
> - if (mach_port_deallocate_debug)
> - SoftDebugger("ipc_entry_lookup");
> -}
> +#define ipc_entry_lookup_failed(msg, port_name)  
> \
> +MACRO_BEGIN  \
> + if (MACH_PORT_NAME_VALID(port_name)) {  \
> + printf("task %.*s looked up a bogus port %lu for %d, "  \
> +"most probably a bug.\n",\
> + (int) sizeof current_task()->name,  \
> + current_task()->name,   \
> + (unsigned long) (port_name),\
> + (msg)->msgh_id);\
> + if (mach_port_deallocate_debug) \
> + SoftDebugger("ipc_entry_lookup");   \
> + }   \
> +MACRO_END
>  
>  /*
>   *   Routine:ipc_entry_get
> -- 
> 2.44.0
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 07/17] kern/rdxtree: Fix undefined behavior

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:31 +0300, a ecrit:
> Initializing a variable with itself is undefined, and GCC 14 rightfully
> produces a warning about the variable being used (to initialize itself)
> prior to initialization. X15 sets the variables to 0 instead, so do the
> same in Mach.
> ---
>  kern/rdxtree.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/kern/rdxtree.c b/kern/rdxtree.c
> index a23d6e7e..6d03710c 100644
> --- a/kern/rdxtree.c
> +++ b/kern/rdxtree.c
> @@ -437,7 +437,7 @@ rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t 
> key,
>void *ptr, void ***slotp)
>  {
>  struct rdxtree_node *node, *prev;
> -unsigned int height, shift, index = index;
> +unsigned int height, shift, index = 0;
>  int error;
>  
>  assert(ptr != NULL);
> @@ -513,7 +513,7 @@ rdxtree_insert_alloc_common(struct rdxtree *tree, void 
> *ptr,
>  rdxtree_key_t *keyp, void ***slotp)
>  {
>  struct rdxtree_node *node, *prev;
> -unsigned int height, shift, index = index;
> +unsigned int height, shift, index = 0;
>  rdxtree_key_t key;
>  int error;
>  
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 06/17] kern/syscall_subr.c: Use copyin()/copyout() to access user memory

2024-03-27 Thread Samuel Thibault
Sergey Bugaev, le mer. 27 mars 2024 19:18:30 +0300, a ecrit:
> It's not always possible to directly access user memory from kernel
> mode. While it's in theory a lot more expensive to fetch each character
> to be printed separately, mach_print() is only a debugging facility, and
> it's not supposed to be used for printing large amounts of data.

Yes, but the atomicity of mach_print is really useful when debugging
issues with several translators etc.

Could you make it use a buffer so we get atomicity for e.g. a hundred
characters?

Samuel

> ---
>  kern/syscall_subr.c | 11 ++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/kern/syscall_subr.c b/kern/syscall_subr.c
> index e0057d94..0027be29 100644
> --- a/kern/syscall_subr.c
> +++ b/kern/syscall_subr.c
> @@ -43,6 +43,7 @@
>  #include 
>  #include 
>  #include  /* for splsched */
> +#include   /* for copyin */
>  
>  #if  MACH_FIXPRI
>  #include 
> @@ -381,6 +382,14 @@ thread_depress_abort(thread_t thread)
>  void
>  mach_print(const char *s)
>  {
> - printf("%s", s);
> + charc;
> + while (TRUE) {
> + if (copyin(s, &c, 1))
> + return;
> + if (c == 0)
> + break;
> + printf("%c", c);
> + s++;
> + }
>  }
>  #endif /* MACH_KDB */
> -- 
> 2.44.0



Re: [PATCH 05/17] gsync: Use copyin()/copyout() to access user memory

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:29 +0300, a ecrit:
> Depending on the architecture and setup, it may not be possible to
> access user memory directly, for example, due to user mode mappings not
> being accessible from kernel mode (x86 SMAP, AArch64 PAN). There are
> dedicated machine-specific copyin()/copyout() routines that know how to
> access user memory from the kernel; use them.
> ---
>  kern/gsync.c | 38 +++---
>  1 file changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/kern/gsync.c b/kern/gsync.c
> index 31b564ca..656e47dd 100644
> --- a/kern/gsync.c
> +++ b/kern/gsync.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /* An entry in the global hash table. */
>  struct gsync_hbucket
> @@ -254,9 +255,28 @@ kern_return_t gsync_wait (task_t task, vm_offset_t addr,
>  
>boolean_t equal;
>if (! remote)
> -equal = ((unsigned int *)addr)[0] == lo &&
> -  ((flags & GSYNC_QUAD) == 0 ||
> -   ((unsigned int *)addr)[1] == hi);
> +{
> +  unsigned int value;
> +
> +  if (copyin ((const void *) addr, &value, 4))
> + {
> +   vm_map_unlock_read (task->map);
> +   kmutex_unlock (&hbp->lock);
> +   return KERN_INVALID_ADDRESS;
> + }
> +
> +  equal = (value == lo);
> +  if (flags & GSYNC_QUAD)
> + {
> +   if (copyin ((const void *) (addr + 4), &value, 4))
> + {
> +   vm_map_unlock_read (task->map);
> +   kmutex_unlock (&hbp->lock);
> +   return KERN_INVALID_ADDRESS;
> + }
> +   equal = equal && (value == hi);
> + }
> +}
>else
>  {
>vm_offset_t paddr = temp_mapping (&va, addr, VM_PROT_READ);
> @@ -388,11 +408,15 @@ kern_return_t gsync_wake (task_t task,
>  }
>  
>addr = paddr + (addr & (PAGE_SIZE - 1));
> +  *(unsigned int *)addr = val;
> +  vm_map_remove (kernel_map, addr, addr + sizeof (int));
> +}
> +  else if (copyout (&val, (void *) addr, 4))
> +{
> +  kmutex_unlock (&hbp->lock);
> +  vm_map_unlock_read (task->map);
> +  return KERN_INVALID_ADDRESS;
>  }
> -
> -  *(unsigned int *)addr = val;
> -  if (task != current_task ())
> -vm_map_remove (kernel_map, addr, addr + sizeof (int));
>  }
>  
>vm_map_unlock_read (task->map);
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 04/17] Load 64-bit ELFs on all 64-bit ports

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:28 +0300, a ecrit:
> Not only on x86_64.
> ---
>  include/mach/exec/elf.h | 4 ++--
>  kern/exception.c| 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/include/mach/exec/elf.h b/include/mach/exec/elf.h
> index 42920e25..55304496 100644
> --- a/include/mach/exec/elf.h
> +++ b/include/mach/exec/elf.h
> @@ -212,7 +212,7 @@ typedef struct elf64_sym {
>  Elf64_Xword  st_size;
>  } Elf64_Sym;
>  
> -#ifdef __x86_64__
> +#ifdef __LP64__
>  #define Elf_Sym Elf64_Sym
>  #define Elf_Shdr Elf64_Shdr
>  #else
> @@ -350,7 +350,7 @@ typedef struct {
>  #define DT_TEXTREL   22
>  #define DT_JMPREL23
>  
> -#if defined(__x86_64__) && ! defined(USER32)
> +#if defined(__LP64__) && ! defined(USER32)
>  typedef Elf64_Ehdr Elf_Ehdr;
>  typedef Elf64_Phdr Elf_Phdr;
>  #else
> diff --git a/kern/exception.c b/kern/exception.c
> index 15f29705..7139b466 100644
> --- a/kern/exception.c
> +++ b/kern/exception.c
> @@ -283,7 +283,7 @@ struct mach_exception {
>  #define  INTEGER_T_SIZE_IN_BITS  (8 * sizeof(integer_t))
>  #define  INTEGER_T_TYPE  MACH_MSG_TYPE_INTEGER_T
>  #define RPC_LONG_INTEGER_T_SIZE_IN_BITS  (8 * sizeof(rpc_long_integer_t))
> -#if defined(__x86_64__) && !defined(USER32)
> +#if defined(__LP64__) && !defined(USER32)
>  #define RPC_LONG_INTEGER_T_TYPE  MACH_MSG_TYPE_INTEGER_64
>  #else
>  #define RPC_LONG_INTEGER_T_TYPE  MACH_MSG_TYPE_INTEGER_32
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 03/17] Use the x86_64 message ABI on all 64-bit ports

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:27 +0300, a ecrit:
> ---
>  include/mach/message.h | 10 +-
>  ipc/ipc_kmsg.c |  4 ++--
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/include/mach/message.h b/include/mach/message.h
> index 9790ef98..87b83951 100644
> --- a/include/mach/message.h
> +++ b/include/mach/message.h
> @@ -240,7 +240,7 @@ typedef struct {
>  } mach_port_name_inlined_t;
>  
>  typedef struct  {
> -#ifdef __x86_64__
> +#ifdef __LP64__
>  /*
>   * For 64 bits, this struct is 8 bytes long so we
>   * can pack the same amount of information as mach_msg_type_long_t.
> @@ -275,9 +275,9 @@ typedef struct  {
>  } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_t;
>  
>  typedef struct {
> -#ifdef __x86_64__
> +#ifdef __LP64__
>  union {
> -/* On x86_64 this is equivalent to mach_msg_type_t so use
> +/* On 64-bit this is equivalent to mach_msg_type_t so use
>   * union to overlay with the old field names.  */
>  mach_msg_type_t  msgtl_header;
>  struct {
> @@ -298,7 +298,7 @@ typedef struct {
>  #endif
>  } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_long_t;
>  
> -#ifdef __x86_64__
> +#ifdef __LP64__
>  #ifdef __cplusplus
>  #if __cplusplus >= 201103L
>  static_assert (sizeof (mach_msg_type_t) == sizeof (mach_msg_type_long_t),
> @@ -401,7 +401,7 @@ typedef integer_t mach_msg_option_t;
>  
>  #define MACH_SEND_ALWAYS 0x0001  /* internal use only */
>  
> -#ifdef __x86_64__
> +#ifdef __LP64__
>  #if defined(KERNEL) && defined(USER32)
>  #define MACH_MSG_USER_ALIGNMENT 4
>  #else
> diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
> index 179c43fa..b23cae7c 100644
> --- a/ipc/ipc_kmsg.c
> +++ b/ipc/ipc_kmsg.c
> @@ -1357,7 +1357,7 @@ ipc_kmsg_copyin_body(
>  
>   if ((is_port && !is_inline && (size != 
> PORT_NAME_T_SIZE_IN_BITS)) ||
>   (is_port && is_inline && (size != PORT_T_SIZE_IN_BITS)) ||
> -#ifndef __x86_64__
> +#ifndef __LP64__
>   (longform && ((type->msgtl_header.msgt_name != 0) ||
> (type->msgtl_header.msgt_size != 0) ||
> (type->msgtl_header.msgt_number != 0))) ||
> @@ -2876,7 +2876,7 @@ ipc_msg_print(mach_msg_header_t *msgh)
>   is_port = MACH_MSG_TYPE_PORT_ANY(name);
>  
>   if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
> -#ifndef __x86_64__
> +#ifndef __LP64__
>   (longform && ((type->msgtl_header.msgt_name != 0) ||
> (type->msgtl_header.msgt_size != 0) ||
> (type->msgtl_header.msgt_number != 0))) ||
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 02/17] Disable host_kernel_version() everywhere but on i386

2024-03-27 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:26 +0300, a ecrit:
> It's not only x86_64, none of new architectures are going to have it.
> ---
>  include/mach/mach_host.defs | 6 +++---
>  kern/host.c | 4 ++--
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs
> index a8c40af6..8fd9d6b3 100644
> --- a/include/mach/mach_host.defs
> +++ b/include/mach/mach_host.defs
> @@ -161,9 +161,7 @@ routine task_get_assignment(
>   task: task_t;
>   out assigned_set: processor_set_name_t);
>  
> -#if defined(__x86_64__) && !defined(USER32)
> -skip;
> -#else
> +#if defined(__i386__) || (defined(__x86_64__) && defined(USER32))
>  /*
>   *   Get string describing current kernel version.
>   *   Deprecated, use host_get_kernel_version.
> @@ -171,6 +169,8 @@ skip;
>  routine  host_kernel_version(
>   host: host_t;
>   out kernel_version  : kernel_version_t);
> +#else
> +skip;
>  #endif
>  
>  /*
> diff --git a/kern/host.c b/kern/host.c
> index 69394374..53f8bdbd 100644
> --- a/kern/host.c
> +++ b/kern/host.c
> @@ -219,8 +219,8 @@ kern_return_t host_get_kernel_version(
>   return KERN_SUCCESS;
>  }
>  
> -#if !defined(__x86_64__) || defined(USER32)
> -/* Same as above, but does not exist for x86_64.  */
> +#if defined(__i386__) || (defined(__x86_64__) && defined(USER32))
> +/* Same as above, but only exists on i386.  */
>  kern_return_t host_kernel_version(
>   const host_thost,
>   kernel_version_tout_version)
> -- 
> 2.44.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 01/17] elf-load: Respect PT_GNU_STACK

2024-03-27 Thread Samuel Thibault
Hello,

Sergey Bugaev, le mer. 27 mars 2024 19:18:25 +0300, a ecrit:
> diff --git a/include/mach/exec/exec.h b/include/mach/exec/exec.h
> index 94b234b0..29fa897d 100644
> --- a/include/mach/exec/exec.h
> +++ b/include/mach/exec/exec.h
> @@ -51,6 +51,8 @@ typedef struct exec_info
>   /* (ELF) Address of interpreter string for loading shared libraries, 
> null if none.  */
>   vm_offset_t interp;
>  
> + /* Required stack protection.  */
> + vm_prot_t stack_prot;

But it's not getting used anywhere?

Samuel



[PATCH 16/17] tests: Don't ask for executable stack

2024-03-27 Thread Sergey Bugaev
---
 tests/start.S| 2 ++
 tests/syscalls.S | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/tests/start.S b/tests/start.S
index b795bfbd..15970fb9 100644
--- a/tests/start.S
+++ b/tests/start.S
@@ -26,3 +26,5 @@ _start:
 movq%rsp,%rdi
 callq   c_start
 #endif /* __x86_64__ */
+
+   .section .note.GNU-stack,"",%progbits
diff --git a/tests/syscalls.S b/tests/syscalls.S
index df9c9bc0..b1e18aa8 100644
--- a/tests/syscalls.S
+++ b/tests/syscalls.S
@@ -2,3 +2,5 @@
 #include 
 
 kernel_trap(invalid_syscall,-31,0)
+
+   .section .note.GNU-stack,"",%progbits
-- 
2.44.0




[PATCH 00/17] Preparatory patches

2024-03-27 Thread Sergey Bugaev
These are generic, relatively independent patches from the AArch64
branch. I've done a quick build for i386-gnu and things still seem to
build, but please test!

Sergey



[PATCH 04/17] Load 64-bit ELFs on all 64-bit ports

2024-03-27 Thread Sergey Bugaev
Not only on x86_64.
---
 include/mach/exec/elf.h | 4 ++--
 kern/exception.c| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/mach/exec/elf.h b/include/mach/exec/elf.h
index 42920e25..55304496 100644
--- a/include/mach/exec/elf.h
+++ b/include/mach/exec/elf.h
@@ -212,7 +212,7 @@ typedef struct elf64_sym {
 Elf64_Xwordst_size;
 } Elf64_Sym;
 
-#ifdef __x86_64__
+#ifdef __LP64__
 #define Elf_Sym Elf64_Sym
 #define Elf_Shdr Elf64_Shdr
 #else
@@ -350,7 +350,7 @@ typedef struct {
 #define DT_TEXTREL 22
 #define DT_JMPREL  23
 
-#if defined(__x86_64__) && ! defined(USER32)
+#if defined(__LP64__) && ! defined(USER32)
 typedef Elf64_Ehdr Elf_Ehdr;
 typedef Elf64_Phdr Elf_Phdr;
 #else
diff --git a/kern/exception.c b/kern/exception.c
index 15f29705..7139b466 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -283,7 +283,7 @@ struct mach_exception {
 #defineINTEGER_T_SIZE_IN_BITS  (8 * sizeof(integer_t))
 #defineINTEGER_T_TYPE  MACH_MSG_TYPE_INTEGER_T
 #define RPC_LONG_INTEGER_T_SIZE_IN_BITS(8 * sizeof(rpc_long_integer_t))
-#if defined(__x86_64__) && !defined(USER32)
+#if defined(__LP64__) && !defined(USER32)
 #define RPC_LONG_INTEGER_T_TYPEMACH_MSG_TYPE_INTEGER_64
 #else
 #define RPC_LONG_INTEGER_T_TYPEMACH_MSG_TYPE_INTEGER_32
-- 
2.44.0




[PATCH 02/17] Disable host_kernel_version() everywhere but on i386

2024-03-27 Thread Sergey Bugaev
It's not only x86_64, none of new architectures are going to have it.
---
 include/mach/mach_host.defs | 6 +++---
 kern/host.c | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs
index a8c40af6..8fd9d6b3 100644
--- a/include/mach/mach_host.defs
+++ b/include/mach/mach_host.defs
@@ -161,9 +161,7 @@ routine task_get_assignment(
task: task_t;
out assigned_set: processor_set_name_t);
 
-#if defined(__x86_64__) && !defined(USER32)
-skip;
-#else
+#if defined(__i386__) || (defined(__x86_64__) && defined(USER32))
 /*
  * Get string describing current kernel version.
  * Deprecated, use host_get_kernel_version.
@@ -171,6 +169,8 @@ skip;
 routinehost_kernel_version(
host: host_t;
out kernel_version  : kernel_version_t);
+#else
+skip;
 #endif
 
 /*
diff --git a/kern/host.c b/kern/host.c
index 69394374..53f8bdbd 100644
--- a/kern/host.c
+++ b/kern/host.c
@@ -219,8 +219,8 @@ kern_return_t host_get_kernel_version(
return KERN_SUCCESS;
 }
 
-#if !defined(__x86_64__) || defined(USER32)
-/* Same as above, but does not exist for x86_64.  */
+#if defined(__i386__) || (defined(__x86_64__) && defined(USER32))
+/* Same as above, but only exists on i386.  */
 kern_return_t host_kernel_version(
const host_thost,
kernel_version_tout_version)
-- 
2.44.0




[PATCH 01/17] elf-load: Respect PT_GNU_STACK

2024-03-27 Thread Sergey Bugaev
If a bootstrap ELF contains a PT_GNU_STACK phdr, take stack protection
from there.  Otherwise, default to VM_PROT_ALL.
---
 include/mach/exec/elf.h  | 1 +
 include/mach/exec/exec.h | 2 ++
 kern/elf-load.c  | 7 +++
 3 files changed, 10 insertions(+)

diff --git a/include/mach/exec/elf.h b/include/mach/exec/elf.h
index 409947c4..42920e25 100644
--- a/include/mach/exec/elf.h
+++ b/include/mach/exec/elf.h
@@ -300,6 +300,7 @@ typedef struct {
 #define PT_NOTE4
 #define PT_SHLIB   5
 #define PT_PHDR6
+#define PT_GNU_STACK   0x6474e551
 
 #define PT_LOPROC  0x7000
 #define PT_HIPROC  0x7fff
diff --git a/include/mach/exec/exec.h b/include/mach/exec/exec.h
index 94b234b0..29fa897d 100644
--- a/include/mach/exec/exec.h
+++ b/include/mach/exec/exec.h
@@ -51,6 +51,8 @@ typedef struct exec_info
/* (ELF) Address of interpreter string for loading shared libraries, 
null if none.  */
vm_offset_t interp;
 
+   /* Required stack protection.  */
+   vm_prot_t stack_prot;
 } exec_info_t;
 
 typedef int exec_sectype_t;
diff --git a/kern/elf-load.c b/kern/elf-load.c
index ce86327c..596233a8 100644
--- a/kern/elf-load.c
+++ b/kern/elf-load.c
@@ -73,6 +73,8 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t 
*read_exec,
if (actual < phsize)
return EX_CORRUPT;
 
+   out_info->stack_prot = VM_PROT_ALL;
+
for (i = 0; i < x.e_phnum; i++)
{
ph = (Elf_Phdr *)((vm_offset_t)phdr + i * x.e_phentsize);
@@ -89,6 +91,11 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t 
*read_exec,
  ph->p_vaddr + loadbase, 
ph->p_memsz, type);
if (result)
return result;
+   } else if (ph->p_type == PT_GNU_STACK) {
+   out_info->stack_prot = 0;
+   if (ph->p_flags & PF_R) out_info->stack_prot |= 
VM_PROT_READ;
+   if (ph->p_flags & PF_W) out_info->stack_prot |= 
VM_PROT_WRITE;
+   if (ph->p_flags & PF_X) out_info->stack_prot |= 
VM_PROT_EXECUTE;
}
}
 
-- 
2.44.0




[PATCH 17/17] tests: Create tests/ in the build tree before trying to use it

2024-03-27 Thread Sergey Bugaev
---
 tests/user-qemu.mk | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/user-qemu.mk b/tests/user-qemu.mk
index fd5ae1ab..4f8390b6 100644
--- a/tests/user-qemu.mk
+++ b/tests/user-qemu.mk
@@ -130,6 +130,7 @@ SRC_TESTLIB= \
$(MIG_GEN_CC)
 
 tests/errlist.c: $(addprefix $(srcdir)/include/mach/,message.h kern_return.h 
mig_errors.h)
+   mkdir -p tests
echo "/* autogenerated file */" >$@
echo "#include " >>$@
echo "#include " >>$@
-- 
2.44.0




[PATCH 05/17] gsync: Use copyin()/copyout() to access user memory

2024-03-27 Thread Sergey Bugaev
Depending on the architecture and setup, it may not be possible to
access user memory directly, for example, due to user mode mappings not
being accessible from kernel mode (x86 SMAP, AArch64 PAN). There are
dedicated machine-specific copyin()/copyout() routines that know how to
access user memory from the kernel; use them.
---
 kern/gsync.c | 38 +++---
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/kern/gsync.c b/kern/gsync.c
index 31b564ca..656e47dd 100644
--- a/kern/gsync.c
+++ b/kern/gsync.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* An entry in the global hash table. */
 struct gsync_hbucket
@@ -254,9 +255,28 @@ kern_return_t gsync_wait (task_t task, vm_offset_t addr,
 
   boolean_t equal;
   if (! remote)
-equal = ((unsigned int *)addr)[0] == lo &&
-  ((flags & GSYNC_QUAD) == 0 ||
-   ((unsigned int *)addr)[1] == hi);
+{
+  unsigned int value;
+
+  if (copyin ((const void *) addr, &value, 4))
+   {
+ vm_map_unlock_read (task->map);
+ kmutex_unlock (&hbp->lock);
+ return KERN_INVALID_ADDRESS;
+   }
+
+  equal = (value == lo);
+  if (flags & GSYNC_QUAD)
+   {
+ if (copyin ((const void *) (addr + 4), &value, 4))
+   {
+ vm_map_unlock_read (task->map);
+ kmutex_unlock (&hbp->lock);
+ return KERN_INVALID_ADDRESS;
+   }
+ equal = equal && (value == hi);
+   }
+}
   else
 {
   vm_offset_t paddr = temp_mapping (&va, addr, VM_PROT_READ);
@@ -388,11 +408,15 @@ kern_return_t gsync_wake (task_t task,
 }
 
   addr = paddr + (addr & (PAGE_SIZE - 1));
+  *(unsigned int *)addr = val;
+  vm_map_remove (kernel_map, addr, addr + sizeof (int));
+}
+  else if (copyout (&val, (void *) addr, 4))
+{
+  kmutex_unlock (&hbp->lock);
+  vm_map_unlock_read (task->map);
+  return KERN_INVALID_ADDRESS;
 }
-
-  *(unsigned int *)addr = val;
-  if (task != current_task ())
-vm_map_remove (kernel_map, addr, addr + sizeof (int));
 }
 
   vm_map_unlock_read (task->map);
-- 
2.44.0




[PATCH 07/17] kern/rdxtree: Fix undefined behavior

2024-03-27 Thread Sergey Bugaev
Initializing a variable with itself is undefined, and GCC 14 rightfully
produces a warning about the variable being used (to initialize itself)
prior to initialization. X15 sets the variables to 0 instead, so do the
same in Mach.
---
 kern/rdxtree.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kern/rdxtree.c b/kern/rdxtree.c
index a23d6e7e..6d03710c 100644
--- a/kern/rdxtree.c
+++ b/kern/rdxtree.c
@@ -437,7 +437,7 @@ rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t 
key,
   void *ptr, void ***slotp)
 {
 struct rdxtree_node *node, *prev;
-unsigned int height, shift, index = index;
+unsigned int height, shift, index = 0;
 int error;
 
 assert(ptr != NULL);
@@ -513,7 +513,7 @@ rdxtree_insert_alloc_common(struct rdxtree *tree, void *ptr,
 rdxtree_key_t *keyp, void ***slotp)
 {
 struct rdxtree_node *node, *prev;
-unsigned int height, shift, index = index;
+unsigned int height, shift, index = 0;
 rdxtree_key_t key;
 int error;
 
-- 
2.44.0




[PATCH 12/17] tests: Add a more serious mach_msg_server() routine

2024-03-27 Thread Sergey Bugaev
---
 tests/include/testlib.h |  16 ++
 tests/test-syscalls.c   |  40 +
 tests/testlib.c | 123 
 3 files changed, 142 insertions(+), 37 deletions(-)

diff --git a/tests/include/testlib.h b/tests/include/testlib.h
index cdb2ce13..d2367124 100644
--- a/tests/include/testlib.h
+++ b/tests/include/testlib.h
@@ -70,6 +70,22 @@ thread_t test_thread_start(task_t task, 
void(*routine)(void*), void* arg);
 mach_port_t host_priv(void);
 mach_port_t device_priv(void);
 
+extern void mach_msg_destroy(mach_msg_header_t *msg);
+
+extern mach_msg_return_t mach_msg_server(
+   boolean_t   (*demux) (mach_msg_header_t *request,
+ mach_msg_header_t *reply),
+   mach_msg_size_t max_size,
+   mach_port_t rcv_name,
+   mach_msg_option_t   options);
+
+extern mach_msg_return_t mach_msg_server_once(
+   boolean_t   (*demux) (mach_msg_header_t *request,
+ mach_msg_header_t *reply),
+   mach_msg_size_t max_size,
+   mach_port_t rcv_name,
+   mach_msg_option_t   options);
+
 int main(int argc, char *argv[], int envc, char *envp[]);
 
 #endif /* TESTLIB_H */
diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c
index be4df8c3..63c2690a 100644
--- a/tests/test-syscalls.c
+++ b/tests/test-syscalls.c
@@ -49,44 +49,10 @@ kern_return_t catch_exception_raise(mach_port_t 
exception_port,
   last_exc.exception = exception;
   last_exc.code = code;
   last_exc.subcode = subcode;
+  thread_terminate(thread);
   return KERN_SUCCESS;
 }
 
-static char simple_request_data[PAGE_SIZE];
-static char simple_reply_data[PAGE_SIZE];
-int simple_msg_server(boolean_t (*demuxer) (mach_msg_header_t *request,
- mach_msg_header_t *reply),
-  mach_port_t rcv_port_name,
-  int num_msgs)
-{
-  int midx = 0, mok = 0;
-  int ret;
-  mig_reply_header_t *request = (mig_reply_header_t*)simple_request_data;
-  mig_reply_header_t *reply = (mig_reply_header_t*)simple_reply_data;
-  while ((midx - num_msgs) < 0)
-{
-  ret = mach_msg(&request->Head, MACH_RCV_MSG, 0, PAGE_SIZE,
- rcv_port_name, 0, MACH_PORT_NULL);
-  switch (ret)
-{
-case MACH_MSG_SUCCESS:
-  if ((*demuxer)(&request->Head, &reply->Head))
-mok++;  // TODO send reply
-  else
-FAILURE("demuxer didn't handle the message");
-  break;
-default:
-  ASSERT_RET(ret, "receiving in msg_server");
-  break;
-}
-  midx++;
-}
-  if (mok != midx)
-FAILURE("wrong number of message received");
-  return mok != midx;
-}
-
-
 void test_syscall_bad_arg_on_stack(void *arg)
 {
   /* mach_msg() has 7 arguments, so the last one should be always
@@ -152,13 +118,13 @@ int main(int argc, char *argv[], int envc, char *envp[])
 
   memset(&last_exc, 0, sizeof(last_exc));
   test_thread_start(mach_task_self(), test_bad_syscall_num, NULL);
-  ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server");
+  ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, 
MACH_MSG_OPTION_NONE), "error in exc server");
   ASSERT((last_exc.exception == EXC_BAD_INSTRUCTION) && (last_exc.code == 
EXC_I386_INVOP),
  "bad exception for test_bad_syscall_num()");
 
   memset(&last_exc, 0, sizeof(last_exc));
   test_thread_start(mach_task_self(), test_syscall_bad_arg_on_stack, NULL);
-  ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server");
+  ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, 
MACH_MSG_OPTION_NONE), "error in exc server");
   ASSERT((last_exc.exception == EXC_BAD_ACCESS) && (last_exc.code == 
KERN_INVALID_ADDRESS),
  "bad exception for test_syscall_bad_arg_on_stack()");
 
diff --git a/tests/testlib.c b/tests/testlib.c
index d2198830..baf1ce5c 100644
--- a/tests/testlib.c
+++ b/tests/testlib.c
@@ -26,6 +26,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 
@@ -81,6 +82,128 @@ const char* e2s(int err)
   }
 }
 
+void mach_msg_destroy(mach_msg_header_t *msg)
+{
+   mach_port_t tmp;
+
+   tmp = mach_reply_port();
+
+   msg->msgh_local_port = msg->msgh_remote_port;
+   msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,
+   MACH_MSGH_BITS_REMOTE(msg->msgh_bits))
+| MACH_MSGH_BITS_OTHER(msg->msgh_bits);
+
+   mach_msg(msg, MACH_SEND_MSG, msg->msgh_size, 0, MACH_PORT_NULL,
+MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+   mach_port_mod_refs(mach_task_self(), tmp, MACH_PORT_RIGHT_RECEIVE, -1);
+}
+
+mach_msg_return_t mach_msg_server(
+   boolean_t   (*demux) (mach_msg_header_t *request,
+ mach_msg_header_t *reply),
+   mach_msg_size_t max_size,
+  

[PATCH 11/17] tests: Fix halt()

2024-03-27 Thread Sergey Bugaev
Mark it as noreturn, and make sure to halt, not reboot.
---
 tests/include/testlib.h | 2 +-
 tests/testlib.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/include/testlib.h b/tests/include/testlib.h
index a3f3a6a8..cdb2ce13 100644
--- a/tests/include/testlib.h
+++ b/tests/include/testlib.h
@@ -63,7 +63,7 @@ extern const char* TEST_FAILURE_MARKER;
 
 const char* e2s(int err);
 const char* e2s_gnumach(int err);
-void halt();
+extern void __attribute__((noreturn)) halt();
 int msleep(uint32_t timeout);
 thread_t test_thread_start(task_t task, void(*routine)(void*), void* arg);
 
diff --git a/tests/testlib.c b/tests/testlib.c
index 2eaeb591..d2198830 100644
--- a/tests/testlib.c
+++ b/tests/testlib.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -55,7 +56,7 @@ mach_port_t device_priv(void)
 
 void halt()
 {
-  int ret = host_reboot(host_priv_port, 0);
+  int ret = host_reboot(host_priv_port, RB_HALT);
   ASSERT_RET(ret, "host_reboot() failed!");
   while (1)
 ;
-- 
2.44.0




[PATCH 15/17] tests: Make exception subcode a long

2024-03-27 Thread Sergey Bugaev
---
 tests/test-syscalls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c
index 63c2690a..fbfecd9c 100644
--- a/tests/test-syscalls.c
+++ b/tests/test-syscalls.c
@@ -34,7 +34,7 @@ static struct {
   mach_port_t task;
   integer_t exception;
   integer_t code;
-  integer_t subcode;
+  long_integer_t subcode;
 } last_exc;
 kern_return_t catch_exception_raise(mach_port_t exception_port,
 mach_port_t thread, mach_port_t task,
-- 
2.44.0




[PATCH 06/17] kern/syscall_subr.c: Use copyin()/copyout() to access user memory

2024-03-27 Thread Sergey Bugaev
It's not always possible to directly access user memory from kernel
mode. While it's in theory a lot more expensive to fetch each character
to be printed separately, mach_print() is only a debugging facility, and
it's not supposed to be used for printing large amounts of data.
---
 kern/syscall_subr.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kern/syscall_subr.c b/kern/syscall_subr.c
index e0057d94..0027be29 100644
--- a/kern/syscall_subr.c
+++ b/kern/syscall_subr.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include/* for splsched */
+#include /* for copyin */
 
 #ifMACH_FIXPRI
 #include 
@@ -381,6 +382,14 @@ thread_depress_abort(thread_t thread)
 void
 mach_print(const char *s)
 {
-   printf("%s", s);
+   charc;
+   while (TRUE) {
+   if (copyin(s, &c, 1))
+   return;
+   if (c == 0)
+   break;
+   printf("%c", c);
+   s++;
+   }
 }
 #endif /* MACH_KDB */
-- 
2.44.0




[PATCH 09/17] Move copy{in,out}msg declarations to copy_user.h

2024-03-27 Thread Sergey Bugaev
Since they are implemented in copy_user.c
---
 i386/i386/locore.h |  4 
 ipc/copy_user.h| 15 +++
 kern/exception.c   |  1 +
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/i386/i386/locore.h b/i386/i386/locore.h
index 217e6dec..8ff587ed 100644
--- a/i386/i386/locore.h
+++ b/i386/i386/locore.h
@@ -52,10 +52,6 @@ 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);
 #ifdef USER32
 extern int copyoutmsg (const void *kernelbuf, void *userbuf, size_t cn);
-#else
-static inline int copyoutmsg (const void *kernelbuf, void *userbuf, size_t cn) 
{
-   return copyout (kernelbuf, userbuf, cn);
-}
 #endif
 
 extern int inst_fetch (int eip, int cs);
diff --git a/ipc/copy_user.h b/ipc/copy_user.h
index a57b3ee5..33beacd0 100644
--- a/ipc/copy_user.h
+++ b/ipc/copy_user.h
@@ -25,6 +25,21 @@
 #include 
 #include 
 
+int copyinmsg(
+   const void  *userbuf,
+   void*kernelbuf,
+   size_t  usize,
+   size_t  ksize);
+
+#ifdef USER32
+int copyoutmsg(
+   const void  *kernelbuf,
+   void*userbuf,
+   size_t  ksize);
+#else
+#define copyoutmsg copyout
+#endif
+
 /*
  * The copyin_32to64() and copyout_64to32() routines are meant for data types
  * that have different size in kernel and user space. They should be 
independent
diff --git a/kern/exception.c b/kern/exception.c
index 7139b466..cc023d45 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.44.0




[PATCH 13/17] tests: Add vm_page_size

2024-03-27 Thread Sergey Bugaev
---
 tests/include/testlib.h |  2 ++
 tests/testlib.c | 13 +
 2 files changed, 15 insertions(+)

diff --git a/tests/include/testlib.h b/tests/include/testlib.h
index d2367124..035fdc28 100644
--- a/tests/include/testlib.h
+++ b/tests/include/testlib.h
@@ -70,6 +70,8 @@ thread_t test_thread_start(task_t task, 
void(*routine)(void*), void* arg);
 mach_port_t host_priv(void);
 mach_port_t device_priv(void);
 
+extern vm_size_t vm_page_size;
+
 extern void mach_msg_destroy(mach_msg_header_t *msg);
 
 extern mach_msg_return_t mach_msg_server(
diff --git a/tests/testlib.c b/tests/testlib.c
index baf1ce5c..12c5e771 100644
--- a/tests/testlib.c
+++ b/tests/testlib.c
@@ -29,6 +29,11 @@
 #include 
 #include 
 
+#ifdef PAGE_SIZE
+vm_size_t vm_page_size = PAGE_SIZE;
+#else
+vm_size_t vm_page_size;
+#endif
 
 static int argc = 0;
 static char *argv_unknown[] = {"unknown", "m1", "123", "456"};
@@ -212,6 +217,7 @@ mach_msg_return_t mach_msg_server_once(
 void __attribute__((used, retain))
 c_start(void **argptr)
 {
+  kern_return_t kr;
   intptr_t* argcptr = (intptr_t*)argptr;
   argc = argcptr[0];
   argv = (char **) &argcptr[1];
@@ -224,6 +230,13 @@ c_start(void **argptr)
   mach_atoi(argv[1], &host_priv_port);
   mach_atoi(argv[2], &device_master_port);
 
+#ifndef PAGE_SIZE
+  vm_statistics_data_t stats;
+  kr = vm_statistics (mach_task_self(), &stats);
+  ASSERT_RET(kr, "can't get page size");
+  vm_page_size = stats.pagesize;
+#endif
+
   printf("started %s", argv[0]);
   for (int i=1; i

[PATCH 14/17] tests: Use vm_page_size

2024-03-27 Thread Sergey Bugaev
---
 tests/testlib_thread_start.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/tests/testlib_thread_start.c b/tests/testlib_thread_start.c
index fa8af0ea..df4b19ab 100644
--- a/tests/testlib_thread_start.c
+++ b/tests/testlib_thread_start.c
@@ -30,30 +30,33 @@
 #include 
 #include 
 
-/* This is just a temporary mapping to set up the stack */
-static long stack_top[PAGE_SIZE/sizeof(long)] __attribute__ ((aligned 
(PAGE_SIZE)));
-
 thread_t test_thread_start(task_t task, void(*routine)(void*), void* arg) {
-  const vm_size_t stack_size = PAGE_SIZE * 16;
+  const vm_size_t stack_size = vm_page_size * 16;
   kern_return_t ret;
-  vm_address_t stack;
+  vm_address_t stack, local_stack;
+
+  ret = vm_allocate(mach_task_self(), &local_stack, vm_page_size, TRUE);
+  ASSERT_RET(ret, "can't allocate local stack");
 
   ret = vm_allocate(task, &stack, stack_size, TRUE);
   ASSERT_RET(ret, "can't allocate the stack for a new thread");
 
-  ret = vm_protect(task, stack, PAGE_SIZE, FALSE, VM_PROT_NONE);
+  ret = vm_protect(task, stack, vm_page_size, FALSE, VM_PROT_NONE);
   ASSERT_RET(ret, "can't protect the stack from overflows");
 
-  long *top = (long*)((vm_offset_t)stack_top + PAGE_SIZE) - 1;
+  long *top = (long*)(local_stack + vm_page_size) - 1;
 #ifdef __i386__
   *top = (long)arg; /* The argument is passed on the stack on x86_32 */
   *(top - 1) = 0;   /* The return address */
 #elif defined(__x86_64__)
   *top = 0; /* The return address */
 #endif
-  ret = vm_write(task, stack + stack_size - PAGE_SIZE, (vm_offset_t)stack_top, 
PAGE_SIZE);
+  ret = vm_write(task, stack + stack_size - vm_page_size, local_stack, 
vm_page_size);
   ASSERT_RET(ret, "can't initialize the stack for the new thread");
 
+  ret = vm_deallocate(mach_task_self(), local_stack, vm_page_size);
+  ASSERT_RET(ret, "can't deallocate local stack");
+
   thread_t thread;
   ret = thread_create(task, &thread);
   ASSERT_RET(ret, "thread_create()");
-- 
2.44.0




[PATCH 10/17] Make -fno-PIE etc. architecture-dependent

2024-03-27 Thread Sergey Bugaev
There might be good reasons why Mach on x86 shouldn't be built as PIC/
PIE, but there are also very good reasons to support PIE on other
architectures. Potentially implementing KASLR is one such reason; but
also the Linux AArch64 boot protocol (that the AArch64 port will use for
booting) lets the bootloader load the kernel image at any address,
which makes PIC pretty much required.
---
 Makefile.am  | 4 
 i386/Makefrag.am | 4 
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index ad38249b..357e8470 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -79,10 +79,6 @@ AM_CFLAGS += \
-fno-stack-protector
 endif
 
-# We do not support or need position-independent
-AM_CFLAGS += \
-   -no-pie -fno-PIE -fno-pie -fno-pic
-
 # This must be the same size as port names, see e.g. ipc/ipc_entry.c
 AM_CFLAGS += -DRDXTREE_KEY_32
 
diff --git a/i386/Makefrag.am b/i386/Makefrag.am
index 5e7d4740..7a339417 100644
--- a/i386/Makefrag.am
+++ b/i386/Makefrag.am
@@ -170,6 +170,10 @@ gnumach_LINKFLAGS += \
-T '$(srcdir)'/i386/ldscript
 endif
 
+# We do not support or need position-independent
+AM_CFLAGS += \
+   -no-pie -fno-PIE -fno-pie -fno-pic
+
 AM_CFLAGS += \
-mno-3dnow \
-mno-mmx \
-- 
2.44.0




[PATCH 08/17] ipc: Turn ipc_entry_lookup_failed() into a macro

2024-03-27 Thread Sergey Bugaev
ipc_entry_lookup_failed() is used with both mach_msg_user_header_t and
mach_msg_header_t arguments, which are different types. Make it into a
macro, so it works with both.
---
 ipc/ipc_space.h | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h
index 96d58942..9adbd3f7 100644
--- a/ipc/ipc_space.h
+++ b/ipc/ipc_space.h
@@ -159,15 +159,19 @@ ipc_entry_lookup(
 
 extern volatile boolean_t mach_port_deallocate_debug;
 
-static inline void
-ipc_entry_lookup_failed(mach_msg_header_t *msg, mach_port_name_t name)
-{
-   if (name == MACH_PORT_NAME_NULL || name == MACH_PORT_NAME_DEAD)
-   return;
-   printf("task %.*s looked up a bogus port %lu for %d, most probably a 
bug.\n", (int) sizeof current_task()->name, current_task()->name, (unsigned 
long) name, msg->msgh_id);
-   if (mach_port_deallocate_debug)
-   SoftDebugger("ipc_entry_lookup");
-}
+#define ipc_entry_lookup_failed(msg, port_name)
\
+MACRO_BEGIN\
+   if (MACH_PORT_NAME_VALID(port_name)) {  \
+   printf("task %.*s looked up a bogus port %lu for %d, "  \
+  "most probably a bug.\n",\
+   (int) sizeof current_task()->name,  \
+   current_task()->name,   \
+   (unsigned long) (port_name),\
+   (msg)->msgh_id);\
+   if (mach_port_deallocate_debug) \
+   SoftDebugger("ipc_entry_lookup");   \
+   }   \
+MACRO_END
 
 /*
  * Routine:ipc_entry_get
-- 
2.44.0




[PATCH 03/17] Use the x86_64 message ABI on all 64-bit ports

2024-03-27 Thread Sergey Bugaev
---
 include/mach/message.h | 10 +-
 ipc/ipc_kmsg.c |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/mach/message.h b/include/mach/message.h
index 9790ef98..87b83951 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -240,7 +240,7 @@ typedef struct {
 } mach_port_name_inlined_t;
 
 typedef struct  {
-#ifdef __x86_64__
+#ifdef __LP64__
 /*
  * For 64 bits, this struct is 8 bytes long so we
  * can pack the same amount of information as mach_msg_type_long_t.
@@ -275,9 +275,9 @@ typedef struct  {
 } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_t;
 
 typedef struct {
-#ifdef __x86_64__
+#ifdef __LP64__
 union {
-/* On x86_64 this is equivalent to mach_msg_type_t so use
+/* On 64-bit this is equivalent to mach_msg_type_t so use
  * union to overlay with the old field names.  */
 mach_msg_type_tmsgtl_header;
 struct {
@@ -298,7 +298,7 @@ typedef struct {
 #endif
 } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_long_t;
 
-#ifdef __x86_64__
+#ifdef __LP64__
 #ifdef __cplusplus
 #if __cplusplus >= 201103L
 static_assert (sizeof (mach_msg_type_t) == sizeof (mach_msg_type_long_t),
@@ -401,7 +401,7 @@ typedef integer_t mach_msg_option_t;
 
 #define MACH_SEND_ALWAYS   0x0001  /* internal use only */
 
-#ifdef __x86_64__
+#ifdef __LP64__
 #if defined(KERNEL) && defined(USER32)
 #define MACH_MSG_USER_ALIGNMENT 4
 #else
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index 179c43fa..b23cae7c 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -1357,7 +1357,7 @@ ipc_kmsg_copyin_body(
 
if ((is_port && !is_inline && (size != 
PORT_NAME_T_SIZE_IN_BITS)) ||
(is_port && is_inline && (size != PORT_T_SIZE_IN_BITS)) ||
-#ifndef __x86_64__
+#ifndef __LP64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||
  (type->msgtl_header.msgt_number != 0))) ||
@@ -2876,7 +2876,7 @@ ipc_msg_print(mach_msg_header_t *msgh)
is_port = MACH_MSG_TYPE_PORT_ANY(name);
 
if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
-#ifndef __x86_64__
+#ifndef __LP64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||
  (type->msgtl_header.msgt_number != 0))) ||
-- 
2.44.0