1*1b191cb5SApple OSS Distributions #include <stdlib.h>
2*1b191cb5SApple OSS Distributions #include <stdio.h>
3*1b191cb5SApple OSS Distributions #include <pthread.h>
4*1b191cb5SApple OSS Distributions #include <unistd.h>
5*1b191cb5SApple OSS Distributions #include <mach/mach.h>
6*1b191cb5SApple OSS Distributions #include <mach/task.h>
7*1b191cb5SApple OSS Distributions #include <assert.h>
8*1b191cb5SApple OSS Distributions
9*1b191cb5SApple OSS Distributions #define MAX_TEST_NUM 4
10*1b191cb5SApple OSS Distributions
11*1b191cb5SApple OSS Distributions static mach_port_t
alloc_server_port(void)12*1b191cb5SApple OSS Distributions alloc_server_port(void)
13*1b191cb5SApple OSS Distributions {
14*1b191cb5SApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL;
15*1b191cb5SApple OSS Distributions kern_return_t kr;
16*1b191cb5SApple OSS Distributions
17*1b191cb5SApple OSS Distributions kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_port);
18*1b191cb5SApple OSS Distributions assert(kr == 0);
19*1b191cb5SApple OSS Distributions
20*1b191cb5SApple OSS Distributions kr = mach_port_insert_right(mach_task_self(), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND);
21*1b191cb5SApple OSS Distributions assert(kr == 0);
22*1b191cb5SApple OSS Distributions
23*1b191cb5SApple OSS Distributions return server_port;
24*1b191cb5SApple OSS Distributions }
25*1b191cb5SApple OSS Distributions
26*1b191cb5SApple OSS Distributions static mach_port_t
alloc_reply_port()27*1b191cb5SApple OSS Distributions alloc_reply_port()
28*1b191cb5SApple OSS Distributions {
29*1b191cb5SApple OSS Distributions kern_return_t kr;
30*1b191cb5SApple OSS Distributions mach_port_t reply_port = MACH_PORT_NULL;
31*1b191cb5SApple OSS Distributions mach_port_t task = mach_task_self();
32*1b191cb5SApple OSS Distributions
33*1b191cb5SApple OSS Distributions mach_port_options_t opts = {
34*1b191cb5SApple OSS Distributions .flags = MPO_REPLY_PORT | MPO_INSERT_SEND_RIGHT,
35*1b191cb5SApple OSS Distributions };
36*1b191cb5SApple OSS Distributions
37*1b191cb5SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0, &reply_port);
38*1b191cb5SApple OSS Distributions assert(kr == 0);
39*1b191cb5SApple OSS Distributions
40*1b191cb5SApple OSS Distributions return reply_port;
41*1b191cb5SApple OSS Distributions }
42*1b191cb5SApple OSS Distributions
43*1b191cb5SApple OSS Distributions /* The rcv right of the port would be marked immovable. */
44*1b191cb5SApple OSS Distributions static void
test_immovable_receive_right(void)45*1b191cb5SApple OSS Distributions test_immovable_receive_right(void)
46*1b191cb5SApple OSS Distributions {
47*1b191cb5SApple OSS Distributions kern_return_t kr;
48*1b191cb5SApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
49*1b191cb5SApple OSS Distributions struct {
50*1b191cb5SApple OSS Distributions mach_msg_header_t header;
51*1b191cb5SApple OSS Distributions mach_msg_body_t body;
52*1b191cb5SApple OSS Distributions mach_msg_port_descriptor_t desc;
53*1b191cb5SApple OSS Distributions } msg;
54*1b191cb5SApple OSS Distributions
55*1b191cb5SApple OSS Distributions server_port = alloc_server_port();
56*1b191cb5SApple OSS Distributions reply_port = alloc_reply_port();
57*1b191cb5SApple OSS Distributions
58*1b191cb5SApple OSS Distributions msg.header.msgh_remote_port = server_port;
59*1b191cb5SApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
60*1b191cb5SApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
61*1b191cb5SApple OSS Distributions msg.header.msgh_size = sizeof msg;
62*1b191cb5SApple OSS Distributions
63*1b191cb5SApple OSS Distributions msg.body.msgh_descriptor_count = 1;
64*1b191cb5SApple OSS Distributions
65*1b191cb5SApple OSS Distributions msg.desc.name = reply_port;
66*1b191cb5SApple OSS Distributions msg.desc.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
67*1b191cb5SApple OSS Distributions msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
68*1b191cb5SApple OSS Distributions
69*1b191cb5SApple OSS Distributions kr = mach_msg_send(&msg.header);
70*1b191cb5SApple OSS Distributions
71*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client test_immovable_receive_right]: mach_msg2() returned %d\n", kr);
72*1b191cb5SApple OSS Distributions }
73*1b191cb5SApple OSS Distributions
74*1b191cb5SApple OSS Distributions /* The only way you could create a send once right is when you send the port in local port of a mach msg with MAKE_SEND_ONCE disposition. */
75*1b191cb5SApple OSS Distributions static void
test_make_send_once_right(void)76*1b191cb5SApple OSS Distributions test_make_send_once_right(void)
77*1b191cb5SApple OSS Distributions {
78*1b191cb5SApple OSS Distributions kern_return_t kr;
79*1b191cb5SApple OSS Distributions mach_port_t reply_port = alloc_reply_port();
80*1b191cb5SApple OSS Distributions kr = mach_port_insert_right(mach_task_self(), reply_port, reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE);
81*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client test_make_send_once_right]: mach_port_insert_right() returned %d\n", kr);
82*1b191cb5SApple OSS Distributions }
83*1b191cb5SApple OSS Distributions
84*1b191cb5SApple OSS Distributions /* The send right of the port would only used for guarding a name in ipc space, it would not allow to send a message. */
85*1b191cb5SApple OSS Distributions static void
test_using_send_right(void)86*1b191cb5SApple OSS Distributions test_using_send_right(void)
87*1b191cb5SApple OSS Distributions {
88*1b191cb5SApple OSS Distributions kern_return_t kr;
89*1b191cb5SApple OSS Distributions mach_port_t reply_port = alloc_reply_port();
90*1b191cb5SApple OSS Distributions struct {
91*1b191cb5SApple OSS Distributions mach_msg_header_t header;
92*1b191cb5SApple OSS Distributions mach_msg_body_t body;
93*1b191cb5SApple OSS Distributions } msg;
94*1b191cb5SApple OSS Distributions
95*1b191cb5SApple OSS Distributions msg.header.msgh_remote_port = reply_port;
96*1b191cb5SApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
97*1b191cb5SApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
98*1b191cb5SApple OSS Distributions msg.header.msgh_size = sizeof msg;
99*1b191cb5SApple OSS Distributions
100*1b191cb5SApple OSS Distributions kr = mach_msg_send(&msg.header);
101*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client test_using_send_right]: mach_msg2() returned %d\n", kr);
102*1b191cb5SApple OSS Distributions }
103*1b191cb5SApple OSS Distributions
104*1b191cb5SApple OSS Distributions /* The send right of the port would only used for guarding a name in ipc space, it would not allowed to get moved. */
105*1b191cb5SApple OSS Distributions static void
test_move_send_right(void)106*1b191cb5SApple OSS Distributions test_move_send_right(void)
107*1b191cb5SApple OSS Distributions {
108*1b191cb5SApple OSS Distributions kern_return_t kr;
109*1b191cb5SApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
110*1b191cb5SApple OSS Distributions struct {
111*1b191cb5SApple OSS Distributions mach_msg_header_t header;
112*1b191cb5SApple OSS Distributions mach_msg_body_t body;
113*1b191cb5SApple OSS Distributions mach_msg_port_descriptor_t desc;
114*1b191cb5SApple OSS Distributions } msg;
115*1b191cb5SApple OSS Distributions
116*1b191cb5SApple OSS Distributions server_port = alloc_server_port();
117*1b191cb5SApple OSS Distributions reply_port = alloc_reply_port();
118*1b191cb5SApple OSS Distributions
119*1b191cb5SApple OSS Distributions msg.header.msgh_remote_port = server_port;
120*1b191cb5SApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
121*1b191cb5SApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
122*1b191cb5SApple OSS Distributions msg.header.msgh_size = sizeof msg;
123*1b191cb5SApple OSS Distributions
124*1b191cb5SApple OSS Distributions msg.body.msgh_descriptor_count = 1;
125*1b191cb5SApple OSS Distributions
126*1b191cb5SApple OSS Distributions msg.desc.name = reply_port;
127*1b191cb5SApple OSS Distributions msg.desc.disposition = MACH_MSG_TYPE_MOVE_SEND;
128*1b191cb5SApple OSS Distributions msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
129*1b191cb5SApple OSS Distributions
130*1b191cb5SApple OSS Distributions kr = mach_msg_send(&msg.header);
131*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client test_move_send_right]: mach_msg2() returned %d\n", kr);
132*1b191cb5SApple OSS Distributions }
133*1b191cb5SApple OSS Distributions
134*1b191cb5SApple OSS Distributions int
main(int argc,char * argv[])135*1b191cb5SApple OSS Distributions main(int argc, char *argv[])
136*1b191cb5SApple OSS Distributions {
137*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client]: My Pid: %d\n", getpid());
138*1b191cb5SApple OSS Distributions
139*1b191cb5SApple OSS Distributions void (*tests[MAX_TEST_NUM])(void) = {
140*1b191cb5SApple OSS Distributions test_immovable_receive_right,
141*1b191cb5SApple OSS Distributions test_make_send_once_right,
142*1b191cb5SApple OSS Distributions test_using_send_right,
143*1b191cb5SApple OSS Distributions test_move_send_right
144*1b191cb5SApple OSS Distributions };
145*1b191cb5SApple OSS Distributions
146*1b191cb5SApple OSS Distributions if (argc < 2) {
147*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client]: Specify a test to run.");
148*1b191cb5SApple OSS Distributions exit(-1);
149*1b191cb5SApple OSS Distributions }
150*1b191cb5SApple OSS Distributions
151*1b191cb5SApple OSS Distributions int test_num = atoi(argv[1]);
152*1b191cb5SApple OSS Distributions if (test_num >= 0 && test_num < MAX_TEST_NUM) {
153*1b191cb5SApple OSS Distributions (*tests[test_num])();
154*1b191cb5SApple OSS Distributions } else {
155*1b191cb5SApple OSS Distributions printf("[reply_port_defense_client]: Invalid test num. Exiting...\n");
156*1b191cb5SApple OSS Distributions exit(-1);
157*1b191cb5SApple OSS Distributions }
158*1b191cb5SApple OSS Distributions
159*1b191cb5SApple OSS Distributions exit(0);
160*1b191cb5SApple OSS Distributions }
161