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