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