xref: /xnu-8796.141.3/tests/ipc_mach_port.c (revision 1b191cb58250d0705d8a51287127505aa4bc0789)
1*1b191cb5SApple OSS Distributions #include <darwintest.h>
2*1b191cb5SApple OSS Distributions #include <darwintest_multiprocess.h>
3*1b191cb5SApple OSS Distributions #include <launch.h>
4*1b191cb5SApple OSS Distributions #include <servers/bootstrap.h>
5*1b191cb5SApple OSS Distributions #include <sys/sysctl.h>
6*1b191cb5SApple OSS Distributions #include "exc_helpers.h"
7*1b191cb5SApple OSS Distributions 
8*1b191cb5SApple OSS Distributions T_GLOBAL_META(
9*1b191cb5SApple OSS Distributions 	T_META_NAMESPACE("xnu.ipc"),
10*1b191cb5SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
11*1b191cb5SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("IPC"),
12*1b191cb5SApple OSS Distributions 	T_META_RUN_CONCURRENTLY(true));
13*1b191cb5SApple OSS Distributions 
14*1b191cb5SApple OSS Distributions #pragma mark - helpers
15*1b191cb5SApple OSS Distributions 
16*1b191cb5SApple OSS Distributions #define SERVICE_NAME  "com.apple.xnu.test.mach_port"
17*1b191cb5SApple OSS Distributions 
18*1b191cb5SApple OSS Distributions struct one_port_msg {
19*1b191cb5SApple OSS Distributions 	mach_msg_header_t          header;
20*1b191cb5SApple OSS Distributions 	mach_msg_body_t            body;
21*1b191cb5SApple OSS Distributions 	mach_msg_port_descriptor_t port_descriptor;
22*1b191cb5SApple OSS Distributions 	mach_msg_trailer_t         trailer;            // subtract this when sending
23*1b191cb5SApple OSS Distributions };
24*1b191cb5SApple OSS Distributions 
25*1b191cb5SApple OSS Distributions static mach_port_t
server_checkin(void)26*1b191cb5SApple OSS Distributions server_checkin(void)
27*1b191cb5SApple OSS Distributions {
28*1b191cb5SApple OSS Distributions 	mach_port_t mp;
29*1b191cb5SApple OSS Distributions 	kern_return_t kr;
30*1b191cb5SApple OSS Distributions 
31*1b191cb5SApple OSS Distributions 	kr = bootstrap_check_in(bootstrap_port, SERVICE_NAME, &mp);
32*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "bootstrap_check_in");
33*1b191cb5SApple OSS Distributions 	return mp;
34*1b191cb5SApple OSS Distributions }
35*1b191cb5SApple OSS Distributions 
36*1b191cb5SApple OSS Distributions static mach_port_t
server_lookup(void)37*1b191cb5SApple OSS Distributions server_lookup(void)
38*1b191cb5SApple OSS Distributions {
39*1b191cb5SApple OSS Distributions 	mach_port_t mp;
40*1b191cb5SApple OSS Distributions 	kern_return_t kr;
41*1b191cb5SApple OSS Distributions 
42*1b191cb5SApple OSS Distributions 	kr = bootstrap_look_up(bootstrap_port, SERVICE_NAME, &mp);
43*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "bootstrap_look_up");
44*1b191cb5SApple OSS Distributions 	return mp;
45*1b191cb5SApple OSS Distributions }
46*1b191cb5SApple OSS Distributions 
47*1b191cb5SApple OSS Distributions static mach_port_t
make_sr_port(void)48*1b191cb5SApple OSS Distributions make_sr_port(void)
49*1b191cb5SApple OSS Distributions {
50*1b191cb5SApple OSS Distributions 	mach_port_options_t opts = {
51*1b191cb5SApple OSS Distributions 		.flags = MPO_INSERT_SEND_RIGHT,
52*1b191cb5SApple OSS Distributions 	};
53*1b191cb5SApple OSS Distributions 	kern_return_t kr;
54*1b191cb5SApple OSS Distributions 	mach_port_t port;
55*1b191cb5SApple OSS Distributions 
56*1b191cb5SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &opts, 0ull, &port);
57*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_construct");
58*1b191cb5SApple OSS Distributions 	return port;
59*1b191cb5SApple OSS Distributions }
60*1b191cb5SApple OSS Distributions 
61*1b191cb5SApple OSS Distributions static void
destroy_port(mach_port_t port,bool receive,int srights)62*1b191cb5SApple OSS Distributions destroy_port(mach_port_t port, bool receive, int srights)
63*1b191cb5SApple OSS Distributions {
64*1b191cb5SApple OSS Distributions 	kern_return_t kr;
65*1b191cb5SApple OSS Distributions 
66*1b191cb5SApple OSS Distributions 	if (srights) {
67*1b191cb5SApple OSS Distributions 		kr = mach_port_mod_refs(mach_task_self(), port,
68*1b191cb5SApple OSS Distributions 		    MACH_PORT_RIGHT_SEND, -srights);
69*1b191cb5SApple OSS Distributions 		T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "srights -= %d", srights);
70*1b191cb5SApple OSS Distributions 	}
71*1b191cb5SApple OSS Distributions 	if (receive) {
72*1b191cb5SApple OSS Distributions 		kr = mach_port_mod_refs(mach_task_self(), port,
73*1b191cb5SApple OSS Distributions 		    MACH_PORT_RIGHT_RECEIVE, -1);
74*1b191cb5SApple OSS Distributions 		T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "receive -= 1");
75*1b191cb5SApple OSS Distributions 	}
76*1b191cb5SApple OSS Distributions }
77*1b191cb5SApple OSS Distributions 
78*1b191cb5SApple OSS Distributions static void
send_port(mach_msg_id_t id,mach_port_t dest,mach_port_t right,mach_msg_type_name_t disp)79*1b191cb5SApple OSS Distributions send_port(
80*1b191cb5SApple OSS Distributions 	mach_msg_id_t        id,
81*1b191cb5SApple OSS Distributions 	mach_port_t          dest,
82*1b191cb5SApple OSS Distributions 	mach_port_t          right,
83*1b191cb5SApple OSS Distributions 	mach_msg_type_name_t disp)
84*1b191cb5SApple OSS Distributions {
85*1b191cb5SApple OSS Distributions 	struct one_port_msg msg = {
86*1b191cb5SApple OSS Distributions 		.header = {
87*1b191cb5SApple OSS Distributions 			.msgh_remote_port = dest,
88*1b191cb5SApple OSS Distributions 			.msgh_bits        = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND,
89*1b191cb5SApple OSS Distributions 	    0, MACH_MSG_TYPE_MOVE_SEND, MACH_MSGH_BITS_COMPLEX),
90*1b191cb5SApple OSS Distributions 			.msgh_id          = id,
91*1b191cb5SApple OSS Distributions 			.msgh_size        = offsetof(struct one_port_msg, trailer),
92*1b191cb5SApple OSS Distributions 		},
93*1b191cb5SApple OSS Distributions 		.body = {
94*1b191cb5SApple OSS Distributions 			.msgh_descriptor_count = 1,
95*1b191cb5SApple OSS Distributions 		},
96*1b191cb5SApple OSS Distributions 		.port_descriptor = {
97*1b191cb5SApple OSS Distributions 			.name        = right,
98*1b191cb5SApple OSS Distributions 			.disposition = disp,
99*1b191cb5SApple OSS Distributions 			.type        = MACH_MSG_PORT_DESCRIPTOR,
100*1b191cb5SApple OSS Distributions 		},
101*1b191cb5SApple OSS Distributions 	};
102*1b191cb5SApple OSS Distributions 	kern_return_t kr;
103*1b191cb5SApple OSS Distributions 
104*1b191cb5SApple OSS Distributions 	kr = mach_msg(&msg.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
105*1b191cb5SApple OSS Distributions 	    msg.header.msgh_size, 0, MACH_PORT_NULL, 10000, 0);
106*1b191cb5SApple OSS Distributions 
107*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "send(%d)", id);
108*1b191cb5SApple OSS Distributions }
109*1b191cb5SApple OSS Distributions 
110*1b191cb5SApple OSS Distributions #pragma mark - basic test about right deduplication
111*1b191cb5SApple OSS Distributions 
112*1b191cb5SApple OSS Distributions static mach_port_t
receive_port(mach_msg_id_t expected_id,mach_port_t rcv_port,mach_msg_type_name_t expected_disp)113*1b191cb5SApple OSS Distributions receive_port(
114*1b191cb5SApple OSS Distributions 	mach_msg_id_t        expected_id,
115*1b191cb5SApple OSS Distributions 	mach_port_t          rcv_port,
116*1b191cb5SApple OSS Distributions 	mach_msg_type_name_t expected_disp)
117*1b191cb5SApple OSS Distributions {
118*1b191cb5SApple OSS Distributions 	struct one_port_msg msg = { };
119*1b191cb5SApple OSS Distributions 	kern_return_t kr;
120*1b191cb5SApple OSS Distributions 
121*1b191cb5SApple OSS Distributions 	T_LOG("waiting for message %d", expected_id);
122*1b191cb5SApple OSS Distributions 	kr = mach_msg(&msg.header, MACH_RCV_MSG, 0,
123*1b191cb5SApple OSS Distributions 	    sizeof(msg), rcv_port, 0, 0);
124*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "receive(%d)", expected_id);
125*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(msg.header.msgh_id, expected_id, "message id matches");
126*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_NE(msg.header.msgh_bits & MACH_MSGH_BITS_COMPLEX, 0,
127*1b191cb5SApple OSS Distributions 	    "message is complex");
128*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(msg.body.msgh_descriptor_count, 1, "message has one right");
129*1b191cb5SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(msg.port_descriptor.disposition, expected_disp,
130*1b191cb5SApple OSS Distributions 	    "port has right disposition");
131*1b191cb5SApple OSS Distributions 	return msg.port_descriptor.name;
132*1b191cb5SApple OSS Distributions }
133*1b191cb5SApple OSS Distributions 
134*1b191cb5SApple OSS Distributions T_HELPER_DECL(right_dedup_server, "right_dedup_server")
135*1b191cb5SApple OSS Distributions {
136*1b191cb5SApple OSS Distributions 	mach_port_t svc_port = server_checkin();
137*1b191cb5SApple OSS Distributions 	mach_port_t ports[3];
138*1b191cb5SApple OSS Distributions 
139*1b191cb5SApple OSS Distributions 	ports[0] = receive_port(1, svc_port, MACH_MSG_TYPE_MOVE_RECEIVE);
140*1b191cb5SApple OSS Distributions 	ports[1] = receive_port(2, svc_port, MACH_MSG_TYPE_MOVE_SEND);
141*1b191cb5SApple OSS Distributions 	ports[2] = receive_port(3, svc_port, MACH_MSG_TYPE_MOVE_SEND);
142*1b191cb5SApple OSS Distributions 	T_ASSERT_EQ(ports[0], ports[1], "receive, send, send");
143*1b191cb5SApple OSS Distributions 	T_ASSERT_EQ(ports[0], ports[2], "receive, send, send");
144*1b191cb5SApple OSS Distributions 	destroy_port(ports[0], true, 2);
145*1b191cb5SApple OSS Distributions 
146*1b191cb5SApple OSS Distributions 	ports[0] = receive_port(4, svc_port, MACH_MSG_TYPE_MOVE_SEND);
147*1b191cb5SApple OSS Distributions 	ports[1] = receive_port(5, svc_port, MACH_MSG_TYPE_MOVE_RECEIVE);
148*1b191cb5SApple OSS Distributions 	ports[2] = receive_port(6, svc_port, MACH_MSG_TYPE_MOVE_SEND);
149*1b191cb5SApple OSS Distributions 	T_ASSERT_EQ(ports[0], ports[1], "send, receive, send");
150*1b191cb5SApple OSS Distributions 	T_ASSERT_EQ(ports[0], ports[2], "send, receive, send");
151*1b191cb5SApple OSS Distributions 	destroy_port(ports[0], true, 2);
152*1b191cb5SApple OSS Distributions 
153*1b191cb5SApple OSS Distributions 	ports[0] = receive_port(7, svc_port, MACH_MSG_TYPE_MOVE_SEND);
154*1b191cb5SApple OSS Distributions 	ports[1] = receive_port(8, svc_port, MACH_MSG_TYPE_MOVE_SEND);
155*1b191cb5SApple OSS Distributions 	ports[2] = receive_port(9, svc_port, MACH_MSG_TYPE_MOVE_RECEIVE);
156*1b191cb5SApple OSS Distributions 	T_ASSERT_EQ(ports[0], ports[1], "send, send, receive");
157*1b191cb5SApple OSS Distributions 	T_ASSERT_EQ(ports[0], ports[2], "send, send, receive");
158*1b191cb5SApple OSS Distributions 	destroy_port(ports[0], true, 2);
159*1b191cb5SApple OSS Distributions 
160*1b191cb5SApple OSS Distributions 	T_END;
161*1b191cb5SApple OSS Distributions }
162*1b191cb5SApple OSS Distributions 
163*1b191cb5SApple OSS Distributions T_HELPER_DECL(right_dedup_client, "right_dedup_client")
164*1b191cb5SApple OSS Distributions {
165*1b191cb5SApple OSS Distributions 	mach_port_t svc_port = server_lookup();
166*1b191cb5SApple OSS Distributions 	mach_port_t port;
167*1b191cb5SApple OSS Distributions 
168*1b191cb5SApple OSS Distributions 	port = make_sr_port();
169*1b191cb5SApple OSS Distributions 	send_port(1, svc_port, port, MACH_MSG_TYPE_MOVE_RECEIVE);
170*1b191cb5SApple OSS Distributions 	send_port(2, svc_port, port, MACH_MSG_TYPE_COPY_SEND);
171*1b191cb5SApple OSS Distributions 	send_port(3, svc_port, port, MACH_MSG_TYPE_MOVE_SEND);
172*1b191cb5SApple OSS Distributions 
173*1b191cb5SApple OSS Distributions 	port = make_sr_port();
174*1b191cb5SApple OSS Distributions 	send_port(4, svc_port, port, MACH_MSG_TYPE_COPY_SEND);
175*1b191cb5SApple OSS Distributions 	send_port(5, svc_port, port, MACH_MSG_TYPE_MOVE_RECEIVE);
176*1b191cb5SApple OSS Distributions 	send_port(6, svc_port, port, MACH_MSG_TYPE_MOVE_SEND);
177*1b191cb5SApple OSS Distributions 
178*1b191cb5SApple OSS Distributions 	port = make_sr_port();
179*1b191cb5SApple OSS Distributions 	send_port(7, svc_port, port, MACH_MSG_TYPE_COPY_SEND);
180*1b191cb5SApple OSS Distributions 	send_port(8, svc_port, port, MACH_MSG_TYPE_MOVE_SEND);
181*1b191cb5SApple OSS Distributions 	send_port(9, svc_port, port, MACH_MSG_TYPE_MOVE_RECEIVE);
182*1b191cb5SApple OSS Distributions }
183*1b191cb5SApple OSS Distributions 
184*1b191cb5SApple OSS Distributions T_DECL(right_dedup, "make sure right deduplication works")
185*1b191cb5SApple OSS Distributions {
186*1b191cb5SApple OSS Distributions 	dt_helper_t helpers[] = {
187*1b191cb5SApple OSS Distributions 		dt_launchd_helper_domain("com.apple.xnu.test.mach_port.plist",
188*1b191cb5SApple OSS Distributions 	    "right_dedup_server", NULL, LAUNCH_SYSTEM_DOMAIN),
189*1b191cb5SApple OSS Distributions 		dt_fork_helper("right_dedup_client"),
190*1b191cb5SApple OSS Distributions 	};
191*1b191cb5SApple OSS Distributions 	dt_run_helpers(helpers, 2, 600);
192*1b191cb5SApple OSS Distributions }
193