Luca Dariz, le jeu. 28 déc. 2023 20:42:56 +0100, a ecrit: > --- > tests/test-syscalls.c | 149 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 149 insertions(+) > create mode 100644 tests/test-syscalls.c > > diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c > new file mode 100644 > index 00000000..7e4234ac > --- /dev/null > +++ b/tests/test-syscalls.c > @@ -0,0 +1,149 @@ > + > +#include <syscalls.h> > +#include <testlib.h> > + > +#include <mach/exception.h> > +#include <mach/mig_errors.h> > +#include <mach/vm_param.h> > + > +#include <mach.user.h> > +#include <mach_port.user.h> > +#include <exc.server.h> > + > + > +static struct { > + mach_port_t exception_port; > + mach_port_t thread; > + mach_port_t task; > + integer_t exception; > + integer_t code; > + integer_t subcode; > +} last_exc; > +kern_return_t catch_exception_raise(mach_port_t exception_port, > + mach_port_t thread, mach_port_t task, > + integer_t exception, integer_t code, > + long_integer_t subcode) > +{ > + printf("received catch_exception_raise(%u %u %u %d %d %d)\n", > + exception_port, thread, task, exception, code, subcode); > + last_exc.exception_port = exception_port; > + last_exc.thread = thread; > + last_exc.task = task; > + last_exc.exception = exception; > + last_exc.code = code; > + last_exc.subcode = subcode; > + 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 passed on the > stack > + make RSP points the the wrong place to check the access check
"the the" typo > + */ > +#ifdef __x86_64__ > + asm volatile("movq $0x123,%rsp;" \ > + "movq $-25,%rax;" \ > + "syscall;" \ > + ); > +#else > + asm volatile("mov $0x123,%esp;" \ > + "mov $-25,%eax;" \ > + "lcall $0x7,$0x0;" \ > + ); > +#endif > + FAILURE("we shouldn't be here!"); > +} > + > +void test_bad_syscall_num(void *arg) > +{ > +#ifdef __x86_64__ > + asm volatile("movq $0x123456,%rax;" \ > + "syscall;" \ > + ); > +#else > + asm volatile("mov $0x123456,%eax;" \ > + "lcall $0x7,$0x0;" \ > + ); > +#endif > + FAILURE("we shouldn't be here!"); > +} > + > + > +int main(int argc, char *argv[], int envc, char *envp[]) > +{ > + int err; > + mach_port_t excp; > + > + err = mach_port_allocate(mach_task_self (), MACH_PORT_RIGHT_RECEIVE, > &excp); > + ASSERT_RET(err, "creating exception port"); > + > + err = mach_port_insert_right(mach_task_self(), excp, excp, > + MACH_MSG_TYPE_MAKE_SEND); > + ASSERT_RET(err, "inserting sr into exception port"); > + > + err = task_set_special_port(mach_task_self(), TASK_EXCEPTION_PORT, excp); > + ASSERT_RET(err, "setting task exception port"); > + > + /* FIXME: receiving an exception with small size causes GP on 64 bit > userspace */ > + /* mig_reply_header_t msg; */ > + /* err = mach_msg(&msg.Head, /\* The header *\/ */ > + /* MACH_RCV_MSG, */ > + /* 0, */ > + /* sizeof (msg), /\* Max receive Size *\/ */ > + /* excp, */ > + /* 1000, */ > + /* MACH_PORT_NULL); */ > + > + // FIXME: maybe MIG should provide this prototype? > + boolean_t exc_server > + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); > + > + 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((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((last_exc.exception == EXC_BAD_ACCESS) && (last_exc.code == > KERN_INVALID_ADDRESS), > + "bad exception for test_syscall_bad_arg_on_stack()"); > + > + return 0; > +} > -- > 2.39.2