1 #include <stdio.h> 2 #include <mach/message.h> 3 #include <mach/mach_vm.h> 4 #include <mach/mach_port.h> 5 #include <mach/mach_error.h> 6 #include <sys/sysctl.h> 7 #include <sys/wait.h> 8 #include <unistd.h> 9 10 #include <darwintest.h> 11 #include <darwintest_utils.h> 12 13 #include <xpc/private.h> 14 15 T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), 16 T_META_RADAR_COMPONENT_NAME("xnu"), 17 T_META_RADAR_COMPONENT_VERSION("IPC"), 18 T_META_NAMESPACE("xnu.ipc"), 19 T_META_TAG_VM_PREFERRED); 20 21 struct test_msg { 22 mach_msg_header_t header; 23 mach_msg_trailer_t trailer; // subtract this when sending 24 }; 25 26 T_DECL(bootstrap_mig_always_filtered, 27 "'MIG' messages to bootstrap ports from tasks with filtering should always be filtered", 28 T_META_ASROOT(true), T_META_REQUIRES_SYSCTL_EQ("kern.development", 1)) 29 { 30 int new_filter_flag = 1; 31 int rc = sysctlbyname("kern.task_set_filter_msg_flag", NULL, NULL, 32 &new_filter_flag, sizeof(new_filter_flag)); 33 T_ASSERT_POSIX_SUCCESS(rc, "sysctlbyname"); 34 35 struct mach_service_port_info mspi = { 36 .mspi_domain_type = XPC_DOMAIN_PORT, 37 }; 38 strlcpy(mspi.mspi_string_name, "com.apple.xnu.test_bootstrap_msgfilter", 39 sizeof(mspi.mspi_string_name)); 40 41 mach_port_options_t port_opts = { 42 .flags = MPO_SERVICE_PORT | 43 MPO_INSERT_SEND_RIGHT | 44 MPO_CONTEXT_AS_GUARD | 45 MPO_STRICT, 46 .service_port_info = &mspi, 47 }; 48 49 int ctxobj = 0; 50 51 mach_port_t test_bootstrap_port; 52 kern_return_t kr = mach_port_construct(mach_task_self(), &port_opts, 53 (uintptr_t)&ctxobj, &test_bootstrap_port); 54 T_ASSERT_MACH_SUCCESS(kr, "mach_port_construct"); 55 56 // sending a valid 'XPC' msgid should succeed 57 58 mach_msg_id_t permitted_xpc_msgid = 0x01000042; 59 60 struct test_msg msg = { 61 .header = { 62 .msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0), 63 .msgh_size = offsetof(struct test_msg, trailer), 64 .msgh_remote_port = test_bootstrap_port, 65 .msgh_id = permitted_xpc_msgid, 66 }, 67 }; 68 69 mach_msg_option_t msg_opts = MACH_SEND_MSG | MACH_RCV_MSG; 70 kr = mach_msg(&msg.header, msg_opts, msg.header.msgh_size, sizeof(msg), 71 test_bootstrap_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 72 T_ASSERT_MACH_SUCCESS(kr, "send message with valid (XPC) message ID"); 73 74 // sending a 'MIG' msgid (0x00xxxxxx) should fail, non-fatally 75 76 mach_msg_id_t disallowed_mig_msgid = 0x00000042; 77 msg_opts |= MACH_SEND_FILTER_NONFATAL; 78 79 msg = (struct test_msg){ 80 .header = { 81 .msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0), 82 .msgh_size = offsetof(struct test_msg, trailer), 83 .msgh_remote_port = test_bootstrap_port, 84 .msgh_id = disallowed_mig_msgid, 85 }, 86 }; 87 kr = mach_msg(&msg.header, msg_opts, msg.header.msgh_size, sizeof(msg), 88 test_bootstrap_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 89 T_ASSERT_EQ(kr, MACH_SEND_MSG_FILTERED, "message should be filtered"); 90 } 91