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