[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 12/17] tests: Add a more serious mach_msg_server() routine
From: |
Samuel Thibault |
Subject: |
Re: [PATCH 12/17] tests: Add a more serious mach_msg_server() routine |
Date: |
Wed, 27 Mar 2024 19:56:57 +0100 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
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 <sys/reboot.h>
>
> #include <mach.user.h>
> +#include <mach_port.user.h>
> #include <mach_host.user.h>
>
>
> @@ -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,
> + mach_port_t rcv_name,
> + mach_msg_option_t options)
> +{
> + mach_msg_return_t mr;
> + mig_reply_header_t *request;
> + mig_reply_header_t *reply;
> + mig_reply_header_t *tmp;
> + boolean_t handled;
> +
> + request = __builtin_alloca(max_size);
> + reply = __builtin_alloca(max_size);
> +
> +GetRequest:
> + mr = mach_msg(&request->Head, MACH_RCV_MSG|options,
> + 0, max_size, rcv_name,
> + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
> + if (mr)
> + return mr;
> +
> +Handle:
> + handled = demux(&request->Head, &reply->Head);
> + if (!handled)
> + reply->RetCode = MIG_BAD_ID;
> +
> + if (reply->RetCode == MIG_NO_REPLY)
> + goto GetRequest;
> + else if (reply->RetCode != KERN_SUCCESS) {
> + request->Head.msgh_remote_port = MACH_PORT_NULL;
> + mach_msg_destroy(&request->Head);
> + }
> +
> + if (!MACH_PORT_VALID(reply->Head.msgh_remote_port)) {
> + mach_msg_destroy(&reply->Head);
> + goto GetRequest;
> + }
> +
> + tmp = request;
> + request = reply;
> + reply = tmp;
> +
> + mr = mach_msg(&request->Head, MACH_SEND_MSG|MACH_RCV_MSG|options,
> + request->Head.msgh_size, max_size, rcv_name,
> + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
> +
> + if (mr == MACH_MSG_SUCCESS)
> + goto Handle;
> + else if (mr == MACH_SEND_INVALID_DEST) {
> + mach_msg_destroy(&request->Head);
> + goto GetRequest;
> + }
> +
> + return mr;
> +}
> +
> +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)
> +{
> + mach_msg_return_t mr;
> + mig_reply_header_t *request;
> + mig_reply_header_t *reply;
> + boolean_t handled;
> +
> + request = __builtin_alloca(max_size);
> + reply = __builtin_alloca(max_size);
> +
> + mr = mach_msg(&request->Head, MACH_RCV_MSG|options,
> + 0, max_size, rcv_name,
> + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
> + if (mr)
> + return mr;
> +
> + handled = demux(&request->Head, &reply->Head);
> + if (!handled)
> + reply->RetCode = MIG_BAD_ID;
> +
> + if (reply->RetCode == MIG_NO_REPLY)
> + return MACH_MSG_SUCCESS;
> + else if (reply->RetCode != KERN_SUCCESS) {
> + request->Head.msgh_remote_port = MACH_PORT_NULL;
> + mach_msg_destroy(&request->Head);
> + }
> +
> + if (!MACH_PORT_VALID(reply->Head.msgh_remote_port)) {
> + mach_msg_destroy(&reply->Head);
> + return MACH_MSG_SUCCESS;
> + }
> +
> + mr = mach_msg(&reply->Head, MACH_SEND_MSG|options,
> + reply->Head.msgh_size, 0, MACH_PORT_NULL,
> + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
> +
> + if (mr == MACH_SEND_INVALID_DEST)
> + mach_msg_destroy(&reply->Head);
> +
> + return mr;
> +}
> +
> /*
> * Minimal _start() for test modules, we just take the arguments from the
> * kernel, call main() and reboot. As in glibc, we expect the argument
> pointer
> --
> 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, (continued)
- [PATCH 08/17] ipc: Turn ipc_entry_lookup_failed() into a macro, Sergey Bugaev, 2024/03/27
- [PATCH 11/17] tests: Fix halt(), Sergey Bugaev, 2024/03/27
- [PATCH 09/17] Move copy{in,out}msg declarations to copy_user.h, Sergey Bugaev, 2024/03/27
- [PATCH 15/17] tests: Make exception subcode a long, Sergey Bugaev, 2024/03/27
- [PATCH 12/17] tests: Add a more serious mach_msg_server() routine, Sergey Bugaev, 2024/03/27
- Re: [PATCH 12/17] tests: Add a more serious mach_msg_server() routine,
Samuel Thibault <=
- [PATCH 07/17] kern/rdxtree: Fix undefined behavior, Sergey Bugaev, 2024/03/27
- [PATCH 17/17] tests: Create tests/ in the build tree before trying to use it, Sergey Bugaev, 2024/03/27
- [PATCH 16/17] tests: Don't ask for executable stack, Sergey Bugaev, 2024/03/27
- [PATCH 10/17] Make -fno-PIE etc. architecture-dependent, Sergey Bugaev, 2024/03/27
- [PATCH 13/17] tests: Add vm_page_size, Sergey Bugaev, 2024/03/27