• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "base/apple/mach_port_rendezvous.h"
11 
12 #include <mach/mach.h>
13 
14 #include <utility>
15 
16 #include "base/apple/foundation_util.h"
17 #include "base/apple/mach_logging.h"
18 #include "base/at_exit.h"
19 #include "base/command_line.h"
20 #include "base/mac/process_requirement.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/test/multiprocess_test.h"
24 #include "base/test/scoped_feature_list.h"
25 #include "base/test/test_timeouts.h"
26 #include "base/threading/platform_thread.h"
27 #include "base/time/time.h"
28 #include "testing/multiprocess_func_list.h"
29 
30 namespace base {
31 
32 namespace {
33 
34 constexpr MachPortsForRendezvous::key_type kTestPortKey = 'port';
35 
ApplyPeerValidationPolicy(MachPortRendezvousPeerValidationPolicy policy)36 test::ScopedFeatureList ApplyPeerValidationPolicy(
37     MachPortRendezvousPeerValidationPolicy policy) {
38   switch (policy) {
39     case MachPortRendezvousPeerValidationPolicy::kNoValidation:
40       return {};
41     case MachPortRendezvousPeerValidationPolicy::kValidateOnly:
42       return test::ScopedFeatureList(
43           kMachPortRendezvousValidatePeerRequirements);
44     case MachPortRendezvousPeerValidationPolicy::kEnforce:
45       return test::ScopedFeatureList(
46           kMachPortRendezvousEnforcePeerRequirements);
47   }
48 }
49 
50 }  // namespace
51 
52 class MachPortRendezvousServerTest
53     : public MultiProcessTest,
54       public testing::WithParamInterface<
55           MachPortRendezvousPeerValidationPolicy> {
56  public:
client_data()57   std::map<pid_t, MachPortRendezvousServerMac::ClientData>& client_data() {
58     return MachPortRendezvousServerMac::GetInstance()->client_data_;
59   }
60 
61  private:
62   ShadowingAtExitManager at_exit_;
63   test::ScopedFeatureList feature_list_ = ApplyPeerValidationPolicy(GetParam());
64 };
65 
MULTIPROCESS_TEST_MAIN(TakeSendRight)66 MULTIPROCESS_TEST_MAIN(TakeSendRight) {
67   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
68   CHECK(rendezvous_client);
69 
70   CHECK_EQ(1u, rendezvous_client->GetPortCount());
71 
72   apple::ScopedMachSendRight port =
73       rendezvous_client->TakeSendRight(kTestPortKey);
74   CHECK(port.is_valid());
75 
76   mach_msg_base_t msg{};
77   msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
78   msg.header.msgh_size = sizeof(msg);
79   msg.header.msgh_remote_port = port.get();
80   msg.header.msgh_id = 'good';
81 
82   kern_return_t kr =
83       mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0,
84                MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
85   MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg";
86 
87   return 0;
88 }
89 
TEST_P(MachPortRendezvousServerTest,SendRight)90 TEST_P(MachPortRendezvousServerTest, SendRight) {
91   auto* server = MachPortRendezvousServerMac::GetInstance();
92   ASSERT_TRUE(server);
93 
94   apple::ScopedMachReceiveRight port;
95   kern_return_t kr =
96       mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
97                          apple::ScopedMachReceiveRight::Receiver(port).get());
98   ASSERT_EQ(kr, KERN_SUCCESS);
99 
100   MachRendezvousPort rendezvous_port(port.get(), MACH_MSG_TYPE_MAKE_SEND);
101 
102   Process child;
103   {
104     AutoLock lock(server->GetLock());
105     child = SpawnChild("TakeSendRight");
106     server->RegisterPortsForPid(
107         child.Pid(), {std::make_pair(kTestPortKey, rendezvous_port)});
108   }
109 
110   struct : mach_msg_base_t {
111     mach_msg_trailer_t trailer;
112   } msg{};
113   kr = mach_msg(&msg.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg),
114                 port.get(), TestTimeouts::action_timeout().InMilliseconds(),
115                 MACH_PORT_NULL);
116 
117   EXPECT_EQ(kr, KERN_SUCCESS) << mach_error_string(kr);
118   EXPECT_EQ(msg.header.msgh_id, 'good');
119 
120   int exit_code;
121   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
122       child, TestTimeouts::action_timeout(), &exit_code));
123 
124   EXPECT_EQ(0, exit_code);
125 }
126 
MULTIPROCESS_TEST_MAIN(NoRights)127 MULTIPROCESS_TEST_MAIN(NoRights) {
128   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
129   CHECK(rendezvous_client);
130   CHECK_EQ(0u, rendezvous_client->GetPortCount());
131   return 0;
132 }
133 
TEST_P(MachPortRendezvousServerTest,NoRights)134 TEST_P(MachPortRendezvousServerTest, NoRights) {
135   auto* server = MachPortRendezvousServerMac::GetInstance();
136   ASSERT_TRUE(server);
137 
138   Process child = SpawnChild("NoRights");
139 
140   int exit_code;
141   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
142       child, TestTimeouts::action_timeout(), &exit_code));
143 
144   EXPECT_EQ(0, exit_code);
145 }
146 
MULTIPROCESS_TEST_MAIN(Exit42)147 MULTIPROCESS_TEST_MAIN(Exit42) {
148   _exit(42);
149 }
150 
TEST_P(MachPortRendezvousServerTest,CleanupIfNoRendezvous)151 TEST_P(MachPortRendezvousServerTest, CleanupIfNoRendezvous) {
152   auto* server = MachPortRendezvousServerMac::GetInstance();
153   ASSERT_TRUE(server);
154 
155   apple::ScopedMachReceiveRight port;
156   kern_return_t kr =
157       mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
158                          apple::ScopedMachReceiveRight::Receiver(port).get());
159   ASSERT_EQ(kr, KERN_SUCCESS);
160 
161   MachRendezvousPort rendezvous_port(port.get(), MACH_MSG_TYPE_MAKE_SEND);
162 
163   Process child;
164   {
165     AutoLock lock(server->GetLock());
166     child = SpawnChild("Exit42");
167     server->RegisterPortsForPid(
168         child.Pid(), {std::make_pair(kTestPortKey, rendezvous_port)});
169 
170     EXPECT_EQ(1u, client_data().size());
171   }
172 
173   int exit_code;
174   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
175       child, TestTimeouts::action_timeout(), &exit_code));
176 
177   EXPECT_EQ(42, exit_code);
178 
179   // There is no way to synchronize the test code with the asynchronous
180   // delivery of the dispatch process-exit notification. Loop for a short
181   // while for it to be delivered.
182   auto start = TimeTicks::Now();
183   do {
184     if (client_data().size() == 0) {
185       break;
186     }
187     // Sleep is fine because dispatch will process the notification on one of
188     // its workers.
189     PlatformThread::Sleep(Milliseconds(10));
190   } while ((TimeTicks::Now() - start) < TestTimeouts::action_timeout());
191 
192   EXPECT_EQ(0u, client_data().size());
193 }
194 
TEST_P(MachPortRendezvousServerTest,DestroyRight)195 TEST_P(MachPortRendezvousServerTest, DestroyRight) {
196   const struct {
197     // How to create the port.
198     bool insert_send_right;
199 
200     // Disposition for MachRendezvousPort.
201     mach_port_right_t disposition;
202 
203     // After calling DestroyRight.
204     bool is_dead_name;
205     mach_port_urefs_t send_rights;
206   } kCases[] = {
207       {true, MACH_MSG_TYPE_MOVE_RECEIVE, true, 0},
208       {true, MACH_MSG_TYPE_MOVE_SEND, false, 0},
209       {true, MACH_MSG_TYPE_COPY_SEND, false, 1},
210       {true, MACH_MSG_TYPE_MAKE_SEND, false, 1},
211       {false, MACH_MSG_TYPE_MAKE_SEND, false, 0},
212       {true, MACH_MSG_TYPE_MAKE_SEND_ONCE, false, 1},
213       // It's not possible to test MOVE_SEND_ONCE since one cannot
214       // insert_right MAKE_SEND_ONCE.
215   };
216 
217   for (size_t i = 0; i < std::size(kCases); ++i) {
218     SCOPED_TRACE(base::StringPrintf("case %zu", i).c_str());
219     const auto& test = kCases[i];
220 
221     // This test deliberately leaks Mach port rights.
222     mach_port_t port;
223     kern_return_t kr =
224         mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
225     ASSERT_EQ(kr, KERN_SUCCESS);
226 
227     if (test.insert_send_right) {
228       kr = mach_port_insert_right(mach_task_self(), port, port,
229                                   MACH_MSG_TYPE_MAKE_SEND);
230       ASSERT_EQ(kr, KERN_SUCCESS);
231     }
232 
233     MachRendezvousPort rendezvous_port(port, test.disposition);
234     rendezvous_port.Destroy();
235 
236     mach_port_type_t type = 0;
237     kr = mach_port_type(mach_task_self(), port, &type);
238     ASSERT_EQ(kr, KERN_SUCCESS);
239 
240     EXPECT_EQ(type == MACH_PORT_TYPE_DEAD_NAME, test.is_dead_name) << type;
241 
242     mach_port_urefs_t refs = 0;
243     kr =
244         mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, &refs);
245     ASSERT_EQ(kr, KERN_SUCCESS);
246     EXPECT_EQ(refs, test.send_rights);
247   }
248 }
249 
MULTIPROCESS_TEST_MAIN(FailToRendezvous)250 MULTIPROCESS_TEST_MAIN(FailToRendezvous) {
251   // The rendezvous system uses the BaseBundleID to construct the bootstrap
252   // server name, so changing it will result in a failure to look it up.
253   base::apple::SetBaseBundleID("org.chromium.totallyfake");
254   CHECK_EQ(nullptr, base::MachPortRendezvousClient::GetInstance());
255   return 0;
256 }
257 
TEST_P(MachPortRendezvousServerTest,FailToRendezvous)258 TEST_P(MachPortRendezvousServerTest, FailToRendezvous) {
259   auto* server = MachPortRendezvousServerMac::GetInstance();
260   ASSERT_TRUE(server);
261 
262   Process child = SpawnChild("FailToRendezvous");
263 
264   int exit_code;
265   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
266       child, TestTimeouts::action_timeout(), &exit_code));
267 
268   EXPECT_EQ(0, exit_code);
269 }
270 
MULTIPROCESS_TEST_MAIN(ValidateChildCodeSigningRequirement_Success)271 MULTIPROCESS_TEST_MAIN(ValidateChildCodeSigningRequirement_Success) {
272   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
273   CHECK(rendezvous_client);
274 
275   CHECK_EQ(1u, rendezvous_client->GetPortCount());
276 
277   apple::ScopedMachSendRight port =
278       rendezvous_client->TakeSendRight(kTestPortKey);
279   CHECK(port.is_valid());
280 
281   mach_msg_base_t msg{};
282   msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
283   msg.header.msgh_size = sizeof(msg);
284   msg.header.msgh_remote_port = port.get();
285   msg.header.msgh_id = 'good';
286 
287   kern_return_t kr =
288       mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0,
289                MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
290   MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg";
291 
292   return 0;
293 }
294 
TEST_P(MachPortRendezvousServerTest,ValidateChildCodeSigningRequirement_Success)295 TEST_P(MachPortRendezvousServerTest,
296        ValidateChildCodeSigningRequirement_Success) {
297   auto* server = MachPortRendezvousServerMac::GetInstance();
298   ASSERT_TRUE(server);
299 
300   apple::ScopedMachReceiveRight port;
301   kern_return_t kr =
302       mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
303                          apple::ScopedMachReceiveRight::Receiver(port).get());
304   ASSERT_EQ(kr, KERN_SUCCESS);
305 
306   MachRendezvousPort rendezvous_port(port.get(), MACH_MSG_TYPE_MAKE_SEND);
307 
308   Process child;
309   {
310     AutoLock lock(server->GetLock());
311     child = SpawnChild("ValidateChildCodeSigningRequirement_Success");
312     server->RegisterPortsForPid(
313         child.Pid(), {std::make_pair(kTestPortKey, rendezvous_port)});
314     server->SetProcessRequirementForPid(
315         child.Pid(), mac::ProcessRequirement::AlwaysMatchesForTesting());
316   }
317 
318   struct : mach_msg_base_t {
319     mach_msg_trailer_t trailer;
320   } msg{};
321   kr = mach_msg(&msg.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg),
322                 port.get(), TestTimeouts::action_timeout().InMilliseconds(),
323                 MACH_PORT_NULL);
324 
325   EXPECT_EQ(kr, KERN_SUCCESS) << mach_error_string(kr);
326   EXPECT_EQ(msg.header.msgh_id, 'good');
327 
328   int exit_code;
329   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
330       child, TestTimeouts::action_timeout(), &exit_code));
331 
332   EXPECT_EQ(0, exit_code);
333 }
334 
MULTIPROCESS_TEST_MAIN(ValidateChildCodeSigningRequirement_Failed)335 MULTIPROCESS_TEST_MAIN(ValidateChildCodeSigningRequirement_Failed) {
336   auto policy = MachPortRendezvousClientMac::PeerValidationPolicyForTesting();
337   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
338 
339   CHECK(rendezvous_client);
340 
341   CHECK_EQ(policy == MachPortRendezvousPeerValidationPolicy::kEnforce ? 0u : 1u,
342            rendezvous_client->GetPortCount());
343 
344   return 0;
345 }
346 
TEST_P(MachPortRendezvousServerTest,ValidateChildCodeSigningRequirement_Failed)347 TEST_P(MachPortRendezvousServerTest,
348        ValidateChildCodeSigningRequirement_Failed) {
349   auto* server = MachPortRendezvousServerMac::GetInstance();
350   ASSERT_TRUE(server);
351 
352   apple::ScopedMachReceiveRight port;
353   kern_return_t kr =
354       mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
355                          apple::ScopedMachReceiveRight::Receiver(port).get());
356   ASSERT_EQ(kr, KERN_SUCCESS);
357 
358   MachRendezvousPort rendezvous_port(port.get(), MACH_MSG_TYPE_MAKE_SEND);
359 
360   Process child;
361   {
362     AutoLock lock(server->GetLock());
363     child = SpawnChild("ValidateChildCodeSigningRequirement_Failed");
364     server->RegisterPortsForPid(
365         child.Pid(), {std::make_pair(kTestPortKey, rendezvous_port)});
366     server->SetProcessRequirementForPid(
367         child.Pid(), mac::ProcessRequirement::NeverMatchesForTesting());
368   }
369 
370   int exit_code;
371   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
372       child, TestTimeouts::action_timeout(), &exit_code));
373 
374   EXPECT_EQ(0, exit_code);
375 }
376 
377 // Parent validation
378 
MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_Success)379 MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_Success) {
380   MachPortRendezvousClientMac::SetServerProcessRequirement(
381       mac::ProcessRequirement::AlwaysMatchesForTesting());
382   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
383   CHECK(rendezvous_client);
384 
385   CHECK_EQ(1u, rendezvous_client->GetPortCount());
386 
387   apple::ScopedMachSendRight port =
388       rendezvous_client->TakeSendRight(kTestPortKey);
389   CHECK(port.is_valid());
390 
391   mach_msg_base_t msg{};
392   msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
393   msg.header.msgh_size = sizeof(msg);
394   msg.header.msgh_remote_port = port.get();
395   msg.header.msgh_id = 'good';
396 
397   kern_return_t kr =
398       mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0,
399                MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
400   MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg";
401 
402   return 0;
403 }
404 
TEST_P(MachPortRendezvousServerTest,ValidateParentCodeSigningRequirement_Success)405 TEST_P(MachPortRendezvousServerTest,
406        ValidateParentCodeSigningRequirement_Success) {
407   auto* server = MachPortRendezvousServerMac::GetInstance();
408   ASSERT_TRUE(server);
409 
410   apple::ScopedMachReceiveRight port;
411   kern_return_t kr =
412       mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
413                          apple::ScopedMachReceiveRight::Receiver(port).get());
414   ASSERT_EQ(kr, KERN_SUCCESS);
415 
416   MachRendezvousPort rendezvous_port(port.get(), MACH_MSG_TYPE_MAKE_SEND);
417 
418   Process child;
419   {
420     AutoLock lock(server->GetLock());
421     child = SpawnChild("ValidateParentCodeSigningRequirement_Success");
422     server->RegisterPortsForPid(
423         child.Pid(), {std::make_pair(kTestPortKey, rendezvous_port)});
424   }
425 
426   struct : mach_msg_base_t {
427     mach_msg_trailer_t trailer;
428   } msg{};
429   kr = mach_msg(&msg.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg),
430                 port.get(), TestTimeouts::action_timeout().InMilliseconds(),
431                 MACH_PORT_NULL);
432 
433   EXPECT_EQ(kr, KERN_SUCCESS) << mach_error_string(kr);
434   EXPECT_EQ(msg.header.msgh_id, 'good');
435 
436   int exit_code;
437   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
438       child, TestTimeouts::action_timeout(), &exit_code));
439 
440   EXPECT_EQ(0, exit_code);
441 }
442 
MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_NoRights_Success)443 MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_NoRights_Success) {
444   MachPortRendezvousClientMac::SetServerProcessRequirement(
445       mac::ProcessRequirement::AlwaysMatchesForTesting());
446   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
447   CHECK(rendezvous_client);
448   CHECK_EQ(0u, rendezvous_client->GetPortCount());
449   return 0;
450 }
451 
TEST_P(MachPortRendezvousServerTest,ValidateParentCodeSigningRequirement_NoRights_Success)452 TEST_P(MachPortRendezvousServerTest,
453        ValidateParentCodeSigningRequirement_NoRights_Success) {
454   auto* server = MachPortRendezvousServerMac::GetInstance();
455   ASSERT_TRUE(server);
456 
457   Process child =
458       SpawnChild("ValidateParentCodeSigningRequirement_NoRights_Success");
459 
460   int exit_code;
461   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
462       child, TestTimeouts::action_timeout(), &exit_code));
463 
464   EXPECT_EQ(0, exit_code);
465 }
466 
MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_Failure)467 MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_Failure) {
468   MachPortRendezvousClientMac::SetServerProcessRequirement(
469       mac::ProcessRequirement::NeverMatchesForTesting());
470   auto policy = MachPortRendezvousClientMac::PeerValidationPolicyForTesting();
471   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
472   CHECK(policy == MachPortRendezvousPeerValidationPolicy::kEnforce
473             ? !rendezvous_client
474             : bool(rendezvous_client));
475   return 0;
476 }
477 
TEST_P(MachPortRendezvousServerTest,ValidateParentCodeSigningRequirement_Failure)478 TEST_P(MachPortRendezvousServerTest,
479        ValidateParentCodeSigningRequirement_Failure) {
480   auto* server = MachPortRendezvousServerMac::GetInstance();
481   ASSERT_TRUE(server);
482 
483   apple::ScopedMachReceiveRight port;
484   kern_return_t kr =
485       mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
486                          apple::ScopedMachReceiveRight::Receiver(port).get());
487   ASSERT_EQ(kr, KERN_SUCCESS);
488 
489   MachRendezvousPort rendezvous_port(port.get(), MACH_MSG_TYPE_MAKE_SEND);
490 
491   Process child;
492   {
493     AutoLock lock(server->GetLock());
494     child = SpawnChild("ValidateParentCodeSigningRequirement_Failure");
495     server->RegisterPortsForPid(
496         child.Pid(), {std::make_pair(kTestPortKey, rendezvous_port)});
497   }
498 
499   int exit_code;
500   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
501       child, TestTimeouts::action_timeout(), &exit_code));
502 
503   EXPECT_EQ(0, exit_code);
504 }
505 
MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_NoRights_Failure)506 MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_NoRights_Failure) {
507   MachPortRendezvousClientMac::SetServerProcessRequirement(
508       mac::ProcessRequirement::NeverMatchesForTesting());
509   auto policy = MachPortRendezvousClientMac::PeerValidationPolicyForTesting();
510   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
511   CHECK(policy == MachPortRendezvousPeerValidationPolicy::kEnforce
512             ? !rendezvous_client
513             : bool(rendezvous_client));
514   return 0;
515 }
516 
TEST_P(MachPortRendezvousServerTest,ValidateParentCodeSigningRequirement_NoRights_Failure)517 TEST_P(MachPortRendezvousServerTest,
518        ValidateParentCodeSigningRequirement_NoRights_Failure) {
519   auto* server = MachPortRendezvousServerMac::GetInstance();
520   ASSERT_TRUE(server);
521 
522   Process child =
523       SpawnChild("ValidateParentCodeSigningRequirement_NoRights_Failure");
524 
525   int exit_code;
526   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
527       child, TestTimeouts::action_timeout(), &exit_code));
528 
529   EXPECT_EQ(0, exit_code);
530 }
531 
532 // Dynamic-only validation requires that the unit test executable have an
533 // Info.plist embedded in its __TEXT __info_plist section.
MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_DynamicOnly)534 MULTIPROCESS_TEST_MAIN(ValidateParentCodeSigningRequirement_DynamicOnly) {
535   mac::ProcessRequirement requirement =
536       mac::ProcessRequirement::AlwaysMatchesForTesting();
537   requirement.SetShouldCheckDynamicValidityOnlyForTesting();
538   MachPortRendezvousClientMac::SetServerProcessRequirement(requirement);
539   auto* rendezvous_client = MachPortRendezvousClient::GetInstance();
540   CHECK(rendezvous_client);
541   return 0;
542 }
543 
TEST_P(MachPortRendezvousServerTest,ValidateParentCodeSigningRequirement_DynamicOnly)544 TEST_P(MachPortRendezvousServerTest,
545        ValidateParentCodeSigningRequirement_DynamicOnly) {
546   auto* server = MachPortRendezvousServerMac::GetInstance();
547   ASSERT_TRUE(server);
548 
549   Process child =
550       SpawnChild("ValidateParentCodeSigningRequirement_DynamicOnly");
551 
552   int exit_code;
553   ASSERT_TRUE(WaitForMultiprocessTestChildExit(
554       child, TestTimeouts::action_timeout(), &exit_code));
555 
556   EXPECT_EQ(0, exit_code);
557 }
558 
559 INSTANTIATE_TEST_SUITE_P(
560     All,
561     MachPortRendezvousServerTest,
562     testing::Values(MachPortRendezvousPeerValidationPolicy::kNoValidation,
563                     MachPortRendezvousPeerValidationPolicy::kValidateOnly,
564                     MachPortRendezvousPeerValidationPolicy::kEnforce));
565 
566 }  // namespace base
567