xref: /xnu-10063.121.3/tests/exception_tests.c (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1*2c2f96dcSApple OSS Distributions #include <darwintest.h>
2*2c2f96dcSApple OSS Distributions #include <pthread/private.h>
3*2c2f96dcSApple OSS Distributions #include <sys/sysctl.h>
4*2c2f96dcSApple OSS Distributions #include <mach/task.h>
5*2c2f96dcSApple OSS Distributions #include "exc_helpers.h"
6*2c2f96dcSApple OSS Distributions 
7*2c2f96dcSApple OSS Distributions #define EXCEPTION_IDENTITY_PROTECTED 4
8*2c2f96dcSApple OSS Distributions 
9*2c2f96dcSApple OSS Distributions T_GLOBAL_META(
10*2c2f96dcSApple OSS Distributions 	T_META_NAMESPACE("xnu.ipc"),
11*2c2f96dcSApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
12*2c2f96dcSApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("IPC"),
13*2c2f96dcSApple OSS Distributions 	T_META_RUN_CONCURRENTLY(true));
14*2c2f96dcSApple OSS Distributions 
15*2c2f96dcSApple OSS Distributions static size_t
exc_immovable_handler(mach_port_t task,mach_port_t thread,__unused exception_type_t type,__unused mach_exception_data_t codes)16*2c2f96dcSApple OSS Distributions exc_immovable_handler(
17*2c2f96dcSApple OSS Distributions 	mach_port_t task,
18*2c2f96dcSApple OSS Distributions 	mach_port_t thread,
19*2c2f96dcSApple OSS Distributions 	__unused exception_type_t type,
20*2c2f96dcSApple OSS Distributions 	__unused mach_exception_data_t codes)
21*2c2f96dcSApple OSS Distributions {
22*2c2f96dcSApple OSS Distributions 	T_EXPECT_EQ(task, mach_task_self(), "Received immovable task port");
23*2c2f96dcSApple OSS Distributions 	T_EXPECT_EQ(thread, pthread_mach_thread_np(pthread_main_thread_np()),
24*2c2f96dcSApple OSS Distributions 	    "Received immovable thread port");
25*2c2f96dcSApple OSS Distributions 	T_END;
26*2c2f96dcSApple OSS Distributions }
27*2c2f96dcSApple OSS Distributions 
28*2c2f96dcSApple OSS Distributions static size_t
exc_handler_identity_protected(task_id_token_t token,uint64_t thread_id,exception_type_t type,__unused exception_data_t codes)29*2c2f96dcSApple OSS Distributions exc_handler_identity_protected(
30*2c2f96dcSApple OSS Distributions 	task_id_token_t token,
31*2c2f96dcSApple OSS Distributions 	uint64_t thread_id,
32*2c2f96dcSApple OSS Distributions 	exception_type_t type,
33*2c2f96dcSApple OSS Distributions 	__unused exception_data_t codes)
34*2c2f96dcSApple OSS Distributions {
35*2c2f96dcSApple OSS Distributions 	mach_port_t port1, port2;
36*2c2f96dcSApple OSS Distributions 	kern_return_t kr;
37*2c2f96dcSApple OSS Distributions 
38*2c2f96dcSApple OSS Distributions 	T_LOG("Got protected exception!");
39*2c2f96dcSApple OSS Distributions 
40*2c2f96dcSApple OSS Distributions 	port1 = mach_task_self();
41*2c2f96dcSApple OSS Distributions 	kr = task_identity_token_get_task_port(token, TASK_FLAVOR_CONTROL, &port2); /* Immovable control port for self */
42*2c2f96dcSApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "task_identity_token_get_task_port() - CONTROL");
43*2c2f96dcSApple OSS Distributions 	T_EXPECT_EQ(port1, port2, "Control port matches!");
44*2c2f96dcSApple OSS Distributions 
45*2c2f96dcSApple OSS Distributions 	T_END;
46*2c2f96dcSApple OSS Distributions }
47*2c2f96dcSApple OSS Distributions 
48*2c2f96dcSApple OSS Distributions T_DECL(exc_immovable, "Test that exceptions receive immovable ports")
49*2c2f96dcSApple OSS Distributions {
50*2c2f96dcSApple OSS Distributions 	mach_port_t exc_port = create_exception_port(EXC_MASK_BAD_ACCESS);
51*2c2f96dcSApple OSS Distributions 	uint32_t opts = 0;
52*2c2f96dcSApple OSS Distributions 	size_t size = sizeof(&opts);
53*2c2f96dcSApple OSS Distributions 	mach_port_t mp;
54*2c2f96dcSApple OSS Distributions 	kern_return_t kr;
55*2c2f96dcSApple OSS Distributions 
56*2c2f96dcSApple OSS Distributions 	T_LOG("Check if task_exc_guard exception has been enabled\n");
57*2c2f96dcSApple OSS Distributions 	int ret = sysctlbyname("kern.ipc_control_port_options", &opts, &size, NULL, 0);
58*2c2f96dcSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(ret, "sysctlbyname(kern.ipc_control_port_options)");
59*2c2f96dcSApple OSS Distributions 
60*2c2f96dcSApple OSS Distributions 	if ((opts & 0x30) == 0) {
61*2c2f96dcSApple OSS Distributions 		T_SKIP("immovable rights aren't enabled");
62*2c2f96dcSApple OSS Distributions 	}
63*2c2f96dcSApple OSS Distributions 
64*2c2f96dcSApple OSS Distributions 	kr = task_get_special_port(mach_task_self(), TASK_KERNEL_PORT, &mp);
65*2c2f96dcSApple OSS Distributions 	T_EXPECT_MACH_SUCCESS(kr, "task_get_special_port");
66*2c2f96dcSApple OSS Distributions 	T_EXPECT_NE(mp, mach_task_self(), "should receive movable port");
67*2c2f96dcSApple OSS Distributions 
68*2c2f96dcSApple OSS Distributions 	/*
69*2c2f96dcSApple OSS Distributions 	 * do not deallocate the port we received on purpose to check
70*2c2f96dcSApple OSS Distributions 	 * that the exception will not coalesce with the movable port
71*2c2f96dcSApple OSS Distributions 	 * we have in our space now
72*2c2f96dcSApple OSS Distributions 	 */
73*2c2f96dcSApple OSS Distributions 
74*2c2f96dcSApple OSS Distributions 	run_exception_handler(exc_port, exc_immovable_handler);
75*2c2f96dcSApple OSS Distributions 	*(void *volatile*)0 = 0;
76*2c2f96dcSApple OSS Distributions }
77*2c2f96dcSApple OSS Distributions 
78*2c2f96dcSApple OSS Distributions T_DECL(exc_raise_identity_protected, "Test identity-protected exception delivery behavior")
79*2c2f96dcSApple OSS Distributions {
80*2c2f96dcSApple OSS Distributions 	mach_port_t exc_port = create_exception_port_behavior64(EXC_MASK_BAD_ACCESS, EXCEPTION_IDENTITY_PROTECTED);
81*2c2f96dcSApple OSS Distributions 
82*2c2f96dcSApple OSS Distributions 	run_exception_handler_behavior64(exc_port, NULL, exc_handler_identity_protected, EXCEPTION_IDENTITY_PROTECTED);
83*2c2f96dcSApple OSS Distributions 	*(void *volatile*)0 = 0;
84*2c2f96dcSApple OSS Distributions }
85