]> git.saurik.com Git - apple/xnu.git/blame - tests/imm_pinned_control_port_crasher.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / imm_pinned_control_port_crasher.c
CommitLineData
c3c9b80d
A
1#include <mach/mach.h>
2#include <stdlib.h>
3#include <pthread.h>
4#include <unistd.h>
5#include <stdio.h>
6#include <assert.h>
7
8/*
9 * DO NOT run this test file by itself.
10 * This test is meant to be invoked by control_port_options darwintest.
11 *
12 * If hard enforcement for pinned control port is on, pinned_test_main_thread_mod_ref-5 are
13 * expected to generate fatal EXC_GUARD.
14 *
15 * If hard enforcement for immovable control port is on, immovable_test_move_send_task_self-13 are
16 * expected to generate fatal EXC_GUARD.
17 *
18 * The type of exception raised (if any) is checked on control_port_options side.
19 */
20#define MAX_TEST_NUM 13
21
22static int
23attempt_send_immovable_port(mach_port_name_t port, mach_msg_type_name_t disp)
24{
25 mach_port_t server;
26 kern_return_t kr;
27 kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server);
28 assert(kr == 0);
29
30 kr = mach_port_insert_right(mach_task_self(), server, server, MACH_MSG_TYPE_MAKE_SEND);
31 assert(kr == 0);
32
33 struct {
34 mach_msg_header_t header;
35 mach_msg_body_t body;
36 mach_msg_port_descriptor_t desc;
37 } msg;
38
39 msg.header.msgh_remote_port = server;
40 msg.header.msgh_local_port = MACH_PORT_NULL;
41 msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
42 msg.header.msgh_size = sizeof msg;
43
44 msg.body.msgh_descriptor_count = 1;
45
46 msg.desc.name = port;
47 msg.desc.disposition = disp;
48 msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
49
50 return mach_msg_send(&msg.header);
51}
52
53static void
54pinned_test_main_thread_mod_ref()
55{
56 printf("[Crasher]: Mod refs main thread's self port to 0\n");
57 mach_port_t thread_self = mach_thread_self();
58 kern_return_t kr = mach_port_mod_refs(mach_task_self(), thread_self, MACH_PORT_RIGHT_SEND, -2);
59
60 printf("[Crasher pinned_test_main_thread_mod_ref] mach_port_mod_refs returned %s \n.", mach_error_string(kr));
61}
62
63static void*
64pthread_run()
65{
66 printf("[Crasher]: Deallocate pthread_self\n");
67 mach_port_t th_self = pthread_mach_thread_np(pthread_self());
68 kern_return_t kr = mach_port_deallocate(mach_task_self(), th_self);
69
70 printf("[Crasher pinned_test_pthread_dealloc] mach_port_deallocate returned %s \n.", mach_error_string(kr));
71 return NULL;
72}
73
74static void
75pinned_test_pthread_dealloc()
76{
77 printf("[Crasher]: Create a pthread and deallocate its self port\n");
78 pthread_t thread;
79 int ret = pthread_create(&thread, NULL, pthread_run, NULL);
80 assert(ret == 0);
81 ret = pthread_join(thread, NULL);
82 assert(ret == 0);
83}
84
85static void
86pinned_test_task_self_dealloc()
87{
88 printf("[Crasher]: Deallocate mach_task_self twice\n");
89 mach_port_t task_self = mach_task_self();
90 kern_return_t kr = mach_port_deallocate(task_self, task_self);
91 assert(kr == 0);
92 kr = mach_port_deallocate(task_self, task_self);
93
94 printf("[Crasher pinned_test_task_self_dealloc] mach_port_deallocate returned %s \n.", mach_error_string(kr));
95}
96
97static void
98pinned_test_task_self_mod_ref()
99{
100 printf("[Crasher]: Mod refs mach_task_self() to 0\n");
101 kern_return_t kr = mach_port_mod_refs(mach_task_self(), mach_task_self(), MACH_PORT_RIGHT_SEND, -2);
102
103 printf("[Crasher pinned_test_task_self_mod_ref] mach_port_mod_refs returned %s \n.", mach_error_string(kr));
104}
105
106static void
107pinned_test_task_threads_mod_ref()
108{
109 printf("[Crasher]: task_threads should return pinned thread ports. Mod refs them to 0\n");
110 thread_array_t th_list;
111 mach_msg_type_number_t th_cnt;
112 kern_return_t kr;
113 mach_port_t th_kp = mach_thread_self();
114 mach_port_deallocate(mach_task_self(), th_kp);
115
116 kr = task_threads(mach_task_self(), &th_list, &th_cnt);
117 mach_port_deallocate(mach_task_self(), th_list[0]);
118
119 kr = mach_port_mod_refs(mach_task_self(), th_list[0], MACH_PORT_RIGHT_SEND, -1);
120
121 printf("[Crasher pinned_test_task_threads_mod_ref] mach_port_mod_refs returned %s \n.", mach_error_string(kr));
122}
123
124static void
125immovable_test_move_send_task_self()
126{
127 kern_return_t kr;
128 printf("[Crasher]: Move send mach_task_self_\n");
129 kr = attempt_send_immovable_port(mach_task_self(), MACH_MSG_TYPE_MOVE_SEND);
130
131 printf("[Crasher immovable_test_move_send_task_self] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
132}
133
134static void
135immovable_test_copy_send_task_self()
136{
137 kern_return_t kr;
138 printf("[Crasher]: Copy send mach_task_self_\n");
139 kr = attempt_send_immovable_port(mach_task_self(), MACH_MSG_TYPE_COPY_SEND);
140
141 printf("[Crasher immovable_test_copy_send_task_self] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
142}
143
144static void
145immovable_test_move_send_thread_self()
146{
147 kern_return_t kr;
148 printf("[Crasher]: Move send main thread's self port\n");
149 kr = attempt_send_immovable_port(mach_thread_self(), MACH_MSG_TYPE_MOVE_SEND);
150
151 printf("[Crasher immovable_test_move_send_thread_self] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
152}
153
154static void
155immovable_test_copy_send_thread_self()
156{
157 kern_return_t kr;
158 mach_port_t port;
159 printf("[Crasher]: Copy send main thread's self port\n");
160 port = mach_thread_self();
161 kr = attempt_send_immovable_port(port, MACH_MSG_TYPE_COPY_SEND);
162 printf("[Crasher immovable_test_copy_send_thread_self] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
163
164 mach_port_deallocate(mach_task_self(), port);
165}
166
167static void
168immovable_test_copy_send_task_read()
169{
170 kern_return_t kr;
171 mach_port_t port;
172 printf("[Crasher]: Copy send task read port\n");
173 kr = task_get_special_port(mach_task_self(), TASK_READ_PORT, &port);
174 assert(kr == 0);
175 kr = attempt_send_immovable_port(port, MACH_MSG_TYPE_COPY_SEND);
176 printf("[Crasher immovable_test_copy_send_task_read] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
177
178 mach_port_deallocate(mach_task_self(), port);
179}
180
181static void
182immovable_test_copy_send_task_inspect()
183{
184 kern_return_t kr;
185 mach_port_t port;
186 printf("[Crasher]: Move send task inspect port\n");
187 kr = task_get_special_port(mach_task_self(), TASK_INSPECT_PORT, &port);
188 assert(kr == 0);
189 kr = attempt_send_immovable_port(port, MACH_MSG_TYPE_MOVE_SEND);
190 printf("[Crasher immovable_test_copy_send_task_inspect] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
191}
192
193static void
194immovable_test_move_send_thread_inspect()
195{
196 kern_return_t kr;
197 mach_port_t port;
198 mach_port_t th_port = mach_thread_self();
199
200 printf("[Crasher]: Move send thread inspect port\n");
201 kr = thread_get_special_port(th_port, THREAD_INSPECT_PORT, &port);
202 assert(kr == 0);
203 kr = attempt_send_immovable_port(port, MACH_MSG_TYPE_MOVE_SEND);
204 printf("[Crasher immovable_test_move_send_thread_inspect] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
205
206 mach_port_deallocate(mach_task_self(), th_port);
207}
208
209static void
210immovable_test_copy_send_thread_read()
211{
212 kern_return_t kr;
213 mach_port_t port;
214 mach_port_t th_port = mach_thread_self();
215
216 printf("[Crasher]: Copy send thread read port\n");
217 kr = thread_get_special_port(th_port, THREAD_READ_PORT, &port);
218 assert(kr == 0);
219 kr = attempt_send_immovable_port(port, MACH_MSG_TYPE_COPY_SEND);
220 printf("[Crasher immovable_test_copy_send_thread_read] attempt_send_immovable_port returned %s \n.", mach_error_string(kr));
221
222 mach_port_deallocate(mach_task_self(), port);
223 mach_port_deallocate(mach_task_self(), th_port);
224}
225
226int
227main(int argc, char *argv[])
228{
229 void (*tests[MAX_TEST_NUM])(void) = {
230 pinned_test_main_thread_mod_ref,
231 pinned_test_pthread_dealloc,
232 pinned_test_task_self_dealloc,
233 pinned_test_task_self_mod_ref,
234 pinned_test_task_threads_mod_ref,
235
236 immovable_test_move_send_task_self,
237 immovable_test_copy_send_task_self,
238 immovable_test_move_send_thread_self,
239 immovable_test_copy_send_thread_self,
240 immovable_test_copy_send_task_read,
241 immovable_test_copy_send_task_inspect,
242 immovable_test_move_send_thread_inspect,
243 immovable_test_copy_send_thread_read,
244 };
245 printf("[Crasher]: My Pid: %d\n", getpid());
246
247 if (argc < 2) {
248 printf("[Crasher]: Specify a test to run.");
249 exit(-1);
250 }
251
252 int test_num = atoi(argv[1]);
253
254 if (test_num >= 0 && test_num < MAX_TEST_NUM) {
255 (*tests[test_num])();
256 } else {
257 printf("[Crasher]: Invalid test num. Exiting...\n");
258 exit(-1);
259 }
260
261 exit(0);
262}