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