1*bbb1b6f9SApple OSS Distributions #include <stdio.h> 2*bbb1b6f9SApple OSS Distributions #include <stdlib.h> 3*bbb1b6f9SApple OSS Distributions #include <mach/mach.h> 4*bbb1b6f9SApple OSS Distributions #include <mach/mach_port.h> 5*bbb1b6f9SApple OSS Distributions #include <sys/code_signing.h> 6*bbb1b6f9SApple OSS Distributions #include <sys/sysctl.h> 7*bbb1b6f9SApple OSS Distributions #include <darwintest.h> 8*bbb1b6f9SApple OSS Distributions 9*bbb1b6f9SApple OSS Distributions T_GLOBAL_META( 10*bbb1b6f9SApple OSS Distributions T_META_NAMESPACE("xnu.ipc"), 11*bbb1b6f9SApple OSS Distributions T_META_RUN_CONCURRENTLY(TRUE), 12*bbb1b6f9SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"), 13*bbb1b6f9SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("IPC"), 14*bbb1b6f9SApple OSS Distributions T_META_TAG_VM_PREFERRED); 15*bbb1b6f9SApple OSS Distributions 16*bbb1b6f9SApple OSS Distributions #define countof(x) (sizeof(x) / sizeof(x[0])) 17*bbb1b6f9SApple OSS Distributions 18*bbb1b6f9SApple OSS Distributions static void 19*bbb1b6f9SApple OSS Distributions expect_sigkill( 20*bbb1b6f9SApple OSS Distributions void (^fn)(void), 21*bbb1b6f9SApple OSS Distributions const char *description) 22*bbb1b6f9SApple OSS Distributions { 23*bbb1b6f9SApple OSS Distributions pid_t pid = fork(); 24*bbb1b6f9SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "fork"); 25*bbb1b6f9SApple OSS Distributions 26*bbb1b6f9SApple OSS Distributions if (pid == 0) { 27*bbb1b6f9SApple OSS Distributions fn(); 28*bbb1b6f9SApple OSS Distributions T_ASSERT_FAIL("%s: did not receive SIGKILL", description); 29*bbb1b6f9SApple OSS Distributions } else { 30*bbb1b6f9SApple OSS Distributions int status = 0; 31*bbb1b6f9SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(waitpid(pid, &status, 0), "waitpid"); 32*bbb1b6f9SApple OSS Distributions T_EXPECT_EQ(WTERMSIG(status), SIGKILL, 33*bbb1b6f9SApple OSS Distributions "%s exited with %d, expect SIGKILL", description, WTERMSIG(status)); 34*bbb1b6f9SApple OSS Distributions } 35*bbb1b6f9SApple OSS Distributions } 36*bbb1b6f9SApple OSS Distributions 37*bbb1b6f9SApple OSS Distributions T_DECL(mach_port_construct_at_most_one, 38*bbb1b6f9SApple OSS Distributions "mach_port_construct at most one flag policy") 39*bbb1b6f9SApple OSS Distributions { 40*bbb1b6f9SApple OSS Distributions /* verify our at most one flag rule is enforced */ 41*bbb1b6f9SApple OSS Distributions const uint32_t at_most_one_flags[] = { 42*bbb1b6f9SApple OSS Distributions MPO_REPLY_PORT, 43*bbb1b6f9SApple OSS Distributions MPO_CONNECTION_PORT, 44*bbb1b6f9SApple OSS Distributions MPO_SERVICE_PORT, 45*bbb1b6f9SApple OSS Distributions MPO_PROVISIONAL_REPLY_PORT, 46*bbb1b6f9SApple OSS Distributions MPO_EXCEPTION_PORT, 47*bbb1b6f9SApple OSS Distributions MPO_CONNECTION_PORT_WITH_PORT_ARRAY 48*bbb1b6f9SApple OSS Distributions }; 49*bbb1b6f9SApple OSS Distributions 50*bbb1b6f9SApple OSS Distributions 51*bbb1b6f9SApple OSS Distributions for (uint32_t i = 0; i < countof(at_most_one_flags) - 1; ++i) { 52*bbb1b6f9SApple OSS Distributions for (uint32_t j = i + 1; j < countof(at_most_one_flags); ++j) { 53*bbb1b6f9SApple OSS Distributions mach_port_t port; 54*bbb1b6f9SApple OSS Distributions 55*bbb1b6f9SApple OSS Distributions mach_port_options_t opts = { 56*bbb1b6f9SApple OSS Distributions .flags = at_most_one_flags[i] | at_most_one_flags[j] 57*bbb1b6f9SApple OSS Distributions }; 58*bbb1b6f9SApple OSS Distributions 59*bbb1b6f9SApple OSS Distributions kern_return_t kr = mach_port_construct(mach_task_self(), &opts, 0x0, &port); 60*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_ERROR(kr, 61*bbb1b6f9SApple OSS Distributions KERN_INVALID_ARGUMENT, "mach_port_construct failed for at most one flags"); 62*bbb1b6f9SApple OSS Distributions } 63*bbb1b6f9SApple OSS Distributions } 64*bbb1b6f9SApple OSS Distributions } 65*bbb1b6f9SApple OSS Distributions 66*bbb1b6f9SApple OSS Distributions T_DECL(mach_port_construct_invalid_arguments_and_values, 67*bbb1b6f9SApple OSS Distributions "mach_port_construct invalid arguments and values") 68*bbb1b6f9SApple OSS Distributions { 69*bbb1b6f9SApple OSS Distributions kern_return_t kr; 70*bbb1b6f9SApple OSS Distributions mach_port_t port; 71*bbb1b6f9SApple OSS Distributions 72*bbb1b6f9SApple OSS Distributions mach_port_options_t conn_opts = { 73*bbb1b6f9SApple OSS Distributions .flags = MPO_CONNECTION_PORT, 74*bbb1b6f9SApple OSS Distributions .service_port_name = 0x0 75*bbb1b6f9SApple OSS Distributions }; 76*bbb1b6f9SApple OSS Distributions 77*bbb1b6f9SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &conn_opts, 0x0, &port); 78*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_ERROR(kr, 79*bbb1b6f9SApple OSS Distributions KERN_INVALID_ARGUMENT, 80*bbb1b6f9SApple OSS Distributions "MPO_CONNECTION_PORT failed on service_port_name"); 81*bbb1b6f9SApple OSS Distributions 82*bbb1b6f9SApple OSS Distributions conn_opts.service_port_name = MPO_ANONYMOUS_SERVICE; 83*bbb1b6f9SApple OSS Distributions 84*bbb1b6f9SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &conn_opts, 0x0, &port); 85*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "MPO_CONNECTION_PORT succeeds with anonymous service name"); 86*bbb1b6f9SApple OSS Distributions kr = mach_port_destruct(mach_task_self(), port, 0, 0); 87*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "destroy anonymous service name"); 88*bbb1b6f9SApple OSS Distributions 89*bbb1b6f9SApple OSS Distributions mach_port_options_t qlimit_opts = { 90*bbb1b6f9SApple OSS Distributions .flags = MPO_QLIMIT, 91*bbb1b6f9SApple OSS Distributions .mpl.mpl_qlimit = MACH_PORT_QLIMIT_MAX + 1 92*bbb1b6f9SApple OSS Distributions }; 93*bbb1b6f9SApple OSS Distributions 94*bbb1b6f9SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &qlimit_opts, 0x0, &port); 95*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_ERROR(kr, 96*bbb1b6f9SApple OSS Distributions KERN_INVALID_VALUE, 97*bbb1b6f9SApple OSS Distributions "MPO_QLIMIT failed on invalid value"); 98*bbb1b6f9SApple OSS Distributions 99*bbb1b6f9SApple OSS Distributions /* Enumerate on all unknown MPO flags */ 100*bbb1b6f9SApple OSS Distributions mach_port_options_t unknown_flags_opts; 101*bbb1b6f9SApple OSS Distributions for (uint32_t i = 0; i < sizeof(unknown_flags_opts.flags) * CHAR_BIT; ++i) { 102*bbb1b6f9SApple OSS Distributions unknown_flags_opts.flags = MPO_UNUSED_BITS & (1 << i); 103*bbb1b6f9SApple OSS Distributions 104*bbb1b6f9SApple OSS Distributions if (unknown_flags_opts.flags != 0) { 105*bbb1b6f9SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &unknown_flags_opts, 0x0, &port); 106*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_ERROR(kr, 107*bbb1b6f9SApple OSS Distributions KERN_INVALID_ARGUMENT, 108*bbb1b6f9SApple OSS Distributions "Unknown MPO flags 0x%x failed with KERN_INVALID_ARGUMENT", 109*bbb1b6f9SApple OSS Distributions unknown_flags_opts.flags); 110*bbb1b6f9SApple OSS Distributions } 111*bbb1b6f9SApple OSS Distributions } 112*bbb1b6f9SApple OSS Distributions } 113*bbb1b6f9SApple OSS Distributions 114*bbb1b6f9SApple OSS Distributions T_DECL(mach_port_construct_fatal_failure, 115*bbb1b6f9SApple OSS Distributions "mach_port_construct kern defined fatal failures", 116*bbb1b6f9SApple OSS Distributions T_META_IGNORECRASHES(".*mach_port_construct_errors.*"), 117*bbb1b6f9SApple OSS Distributions T_META_ENABLED(!TARGET_OS_OSX && !TARGET_OS_BRIDGE)) 118*bbb1b6f9SApple OSS Distributions { 119*bbb1b6f9SApple OSS Distributions expect_sigkill(^{ 120*bbb1b6f9SApple OSS Distributions mach_port_t port; 121*bbb1b6f9SApple OSS Distributions mach_port_options_t opts = { 122*bbb1b6f9SApple OSS Distributions .flags = MPO_CONNECTION_PORT_WITH_PORT_ARRAY 123*bbb1b6f9SApple OSS Distributions }; 124*bbb1b6f9SApple OSS Distributions (void)mach_port_construct(mach_task_self(), &opts, 0x0, &port); 125*bbb1b6f9SApple OSS Distributions }, "passing MPO_CONNECTION_PORT_WITH_PORT_ARRAY without entitlement"); 126*bbb1b6f9SApple OSS Distributions } 127*bbb1b6f9SApple OSS Distributions 128*bbb1b6f9SApple OSS Distributions T_DECL(mach_port_construct_kern_denied, 129*bbb1b6f9SApple OSS Distributions "mach_port_construct kern defined failures", 130*bbb1b6f9SApple OSS Distributions T_META_TAG_VM_PREFERRED, 131*bbb1b6f9SApple OSS Distributions T_META_ENABLED(!TARGET_OS_OSX && !TARGET_OS_BRIDGE)) 132*bbb1b6f9SApple OSS Distributions { 133*bbb1b6f9SApple OSS Distributions kern_return_t kr; 134*bbb1b6f9SApple OSS Distributions mach_port_t port; 135*bbb1b6f9SApple OSS Distributions mach_port_options_t opts; 136*bbb1b6f9SApple OSS Distributions 137*bbb1b6f9SApple OSS Distributions /* 138*bbb1b6f9SApple OSS Distributions * should fail because only TASK_GRAPHICS_SERVER is allowed to 139*bbb1b6f9SApple OSS Distributions * use MPO_TG_BLOCK_TRACKING. 140*bbb1b6f9SApple OSS Distributions */ 141*bbb1b6f9SApple OSS Distributions opts.flags = MPO_TG_BLOCK_TRACKING; 142*bbb1b6f9SApple OSS Distributions 143*bbb1b6f9SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0x0, &port); 144*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_ERROR(kr, 145*bbb1b6f9SApple OSS Distributions KERN_DENIED, "MPO_TG_BLOCK_TRACKING failed with KERN_DENIED"); 146*bbb1b6f9SApple OSS Distributions } 147