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