1*a325d9c4SApple OSS Distributions #include <stdint.h> 2*a325d9c4SApple OSS Distributions #include <stdio.h> 3*a325d9c4SApple OSS Distributions #include <unistd.h> 4*a325d9c4SApple OSS Distributions 5*a325d9c4SApple OSS Distributions #include <mach/mach.h> 6*a325d9c4SApple OSS Distributions #include <mach/mk_timer.h> 7*a325d9c4SApple OSS Distributions 8*a325d9c4SApple OSS Distributions #include <darwintest.h> 9*a325d9c4SApple OSS Distributions 10*a325d9c4SApple OSS Distributions T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), 11*a325d9c4SApple OSS Distributions T_META_NAMESPACE("xnu.ipc"), 12*a325d9c4SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"), 13*a325d9c4SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("IPC")); 14*a325d9c4SApple OSS Distributions 15*a325d9c4SApple OSS Distributions T_DECL(mktimer_kobject, "mktimer_kobject()", T_META_ALL_VALID_ARCHS(true), T_META_IGNORECRASHES(".*mktimer_kobject.*")) 16*a325d9c4SApple OSS Distributions { 17*a325d9c4SApple OSS Distributions mach_port_t timer_port = MACH_PORT_NULL; 18*a325d9c4SApple OSS Distributions mach_port_t notify_port = MACH_PORT_NULL; 19*a325d9c4SApple OSS Distributions 20*a325d9c4SApple OSS Distributions kern_return_t kr = KERN_SUCCESS; 21*a325d9c4SApple OSS Distributions task_exc_guard_behavior_t old, new; 22*a325d9c4SApple OSS Distributions 23*a325d9c4SApple OSS Distributions /* 24*a325d9c4SApple OSS Distributions * Disable [optional] Mach port guard exceptions to avoid fatal crash 25*a325d9c4SApple OSS Distributions */ 26*a325d9c4SApple OSS Distributions kr = task_get_exc_guard_behavior(mach_task_self(), &old); 27*a325d9c4SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "task_get_exc_guard_behavior"); 28*a325d9c4SApple OSS Distributions new = (old & ~TASK_EXC_GUARD_MP_DELIVER); 29*a325d9c4SApple OSS Distributions kr = task_set_exc_guard_behavior(mach_task_self(), new); 30*a325d9c4SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "task_set_exc_guard_behavior new"); 31*a325d9c4SApple OSS Distributions 32*a325d9c4SApple OSS Distributions /* 33*a325d9c4SApple OSS Distributions * timer port 34*a325d9c4SApple OSS Distributions * This is a receive right which is also a kobject 35*a325d9c4SApple OSS Distributions */ 36*a325d9c4SApple OSS Distributions timer_port = mk_timer_create(); 37*a325d9c4SApple OSS Distributions T_ASSERT_NE(timer_port, (mach_port_t)MACH_PORT_NULL, "mk_timer_create: %s", mach_error_string(kr)); 38*a325d9c4SApple OSS Distributions 39*a325d9c4SApple OSS Distributions mach_port_set_context(mach_task_self(), timer_port, (mach_port_context_t) 0x1); 40*a325d9c4SApple OSS Distributions T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_set_context(timer_port): %s", mach_error_string(kr)); 41*a325d9c4SApple OSS Distributions 42*a325d9c4SApple OSS Distributions /* notification port for the mk_timer port to come back on */ 43*a325d9c4SApple OSS Distributions kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, ¬ify_port); 44*a325d9c4SApple OSS Distributions T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_allocate(notify_port): %s", mach_error_string(kr)); 45*a325d9c4SApple OSS Distributions 46*a325d9c4SApple OSS Distributions kr = mach_port_set_context(mach_task_self(), notify_port, (mach_port_context_t) 0x2); 47*a325d9c4SApple OSS Distributions T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_set_context(notify_port): %s", mach_error_string(kr)); 48*a325d9c4SApple OSS Distributions 49*a325d9c4SApple OSS Distributions T_LOG("timer: 0x%x, notify: 0x%x", timer_port, notify_port); 50*a325d9c4SApple OSS Distributions 51*a325d9c4SApple OSS Distributions /* 52*a325d9c4SApple OSS Distributions * This code generates a mach port guard exception and should be tested with an exception catcher. 53*a325d9c4SApple OSS Distributions * Will be updated in <rdar://problem/70971318> 54*a325d9c4SApple OSS Distributions */ 55*a325d9c4SApple OSS Distributions mach_port_t previous = MACH_PORT_NULL; 56*a325d9c4SApple OSS Distributions 57*a325d9c4SApple OSS Distributions /* request a port-destroyed notification on the timer port */ 58*a325d9c4SApple OSS Distributions kr = mach_port_request_notification(mach_task_self(), timer_port, MACH_NOTIFY_PORT_DESTROYED, 59*a325d9c4SApple OSS Distributions 0, notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); 60*a325d9c4SApple OSS Distributions /* this will ordinarily fail with a guard exception! */ 61*a325d9c4SApple OSS Distributions T_ASSERT_MACH_ERROR(kr, KERN_INVALID_RIGHT, "notifications should NOT work on mk_timer ports!"); 62*a325d9c4SApple OSS Distributions 63*a325d9c4SApple OSS Distributions /* restore the old guard behavior */ 64*a325d9c4SApple OSS Distributions kr = task_set_exc_guard_behavior(mach_task_self(), old); 65*a325d9c4SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "task_set_exc_guard_behavior old"); 66*a325d9c4SApple OSS Distributions 67*a325d9c4SApple OSS Distributions T_LOG("done"); 68*a325d9c4SApple OSS Distributions } 69