| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sandbox/mac/bootstrap_sandbox.h" | 5 #include "sandbox/mac/bootstrap_sandbox.h" |
| 6 | 6 |
| 7 #include <CoreFoundation/CoreFoundation.h> | 7 #include <CoreFoundation/CoreFoundation.h> |
| 8 #import <Foundation/Foundation.h> | 8 #import <Foundation/Foundation.h> |
| 9 #include <mach/mach.h> | 9 #include <mach/mach.h> |
| 10 #include <servers/bootstrap.h> | 10 #include <servers/bootstrap.h> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 policy.rules["com.apple.SecurityServer"] = Rule(POLICY_ALLOW); | 93 policy.rules["com.apple.SecurityServer"] = Rule(POLICY_ALLOW); |
| 94 return policy; | 94 return policy; |
| 95 } | 95 } |
| 96 | 96 |
| 97 void RunChildWithPolicy(int policy_id, | 97 void RunChildWithPolicy(int policy_id, |
| 98 const char* child_name, | 98 const char* child_name, |
| 99 base::ProcessHandle* out_pid) { | 99 base::ProcessHandle* out_pid) { |
| 100 sandbox_->PrepareToForkWithPolicy(policy_id); | 100 sandbox_->PrepareToForkWithPolicy(policy_id); |
| 101 base::LaunchOptions options; | 101 base::LaunchOptions options; |
| 102 options.replacement_bootstrap_name = sandbox_->server_bootstrap_name(); | 102 options.replacement_bootstrap_name = sandbox_->server_bootstrap_name(); |
| 103 base::ProcessHandle pid = SpawnChildWithOptions(child_name, options); | 103 base::Process process = SpawnChildWithOptions(child_name, options); |
| 104 ASSERT_GT(pid, 0); | 104 ASSERT_TRUE(process.IsValid()); |
| 105 sandbox_->FinishedFork(pid); | 105 sandbox_->FinishedFork(process.Handle()); |
| 106 int code = 0; | 106 int code = 0; |
| 107 EXPECT_TRUE(base::WaitForExitCode(pid, &code)); | 107 EXPECT_TRUE(process.WaitForExit(&code)); |
| 108 EXPECT_EQ(0, code); | 108 EXPECT_EQ(0, code); |
| 109 if (out_pid) | 109 if (out_pid) |
| 110 *out_pid = pid; | 110 *out_pid = process.pid(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 protected: | 113 protected: |
| 114 scoped_ptr<BootstrapSandbox> sandbox_; | 114 scoped_ptr<BootstrapSandbox> sandbox_; |
| 115 }; | 115 }; |
| 116 | 116 |
| 117 const char kNotificationTestMain[] = "PostNotification"; | 117 const char kNotificationTestMain[] = "PostNotification"; |
| 118 | 118 |
| 119 // Run the test without the sandbox. | 119 // Run the test without the sandbox. |
| 120 TEST_F(BootstrapSandboxTest, DistributedNotifications_Unsandboxed) { | 120 TEST_F(BootstrapSandboxTest, DistributedNotifications_Unsandboxed) { |
| 121 base::scoped_nsobject<DistributedNotificationObserver> observer( | 121 base::scoped_nsobject<DistributedNotificationObserver> observer( |
| 122 [[DistributedNotificationObserver alloc] init]); | 122 [[DistributedNotificationObserver alloc] init]); |
| 123 | 123 |
| 124 base::ProcessHandle pid = SpawnChild(kNotificationTestMain); | 124 base::Process process = SpawnChild(kNotificationTestMain); |
| 125 ASSERT_GT(pid, 0); | 125 ASSERT_TRUE(process.IsValid()); |
| 126 int code = 0; | 126 int code = 0; |
| 127 EXPECT_TRUE(base::WaitForExitCode(pid, &code)); | 127 EXPECT_TRUE(process.WaitForExit(&code)); |
| 128 EXPECT_EQ(0, code); | 128 EXPECT_EQ(0, code); |
| 129 | 129 |
| 130 [observer waitForNotification]; | 130 [observer waitForNotification]; |
| 131 EXPECT_EQ(1, [observer receivedCount]); | 131 EXPECT_EQ(1, [observer receivedCount]); |
| 132 EXPECT_EQ(pid, [[observer object] intValue]); | 132 EXPECT_EQ(process.pid(), [[observer object] intValue]); |
| 133 } | 133 } |
| 134 | 134 |
| 135 // Run the test with the sandbox enabled without notifications on the policy | 135 // Run the test with the sandbox enabled without notifications on the policy |
| 136 // whitelist. | 136 // whitelist. |
| 137 TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxDeny) { | 137 TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxDeny) { |
| 138 base::scoped_nsobject<DistributedNotificationObserver> observer( | 138 base::scoped_nsobject<DistributedNotificationObserver> observer( |
| 139 [[DistributedNotificationObserver alloc] init]); | 139 [[DistributedNotificationObserver alloc] init]); |
| 140 | 140 |
| 141 sandbox_->RegisterSandboxPolicy(1, BaselinePolicy()); | 141 sandbox_->RegisterSandboxPolicy(1, BaselinePolicy()); |
| 142 RunChildWithPolicy(1, kNotificationTestMain, NULL); | 142 RunChildWithPolicy(1, kNotificationTestMain, NULL); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 | 432 |
| 433 // Set up the policy and register the port. | 433 // Set up the policy and register the port. |
| 434 BootstrapSandboxPolicy policy(BaselinePolicy()); | 434 BootstrapSandboxPolicy policy(BaselinePolicy()); |
| 435 policy.rules["sync"] = Rule(port); | 435 policy.rules["sync"] = Rule(port); |
| 436 sandbox_->RegisterSandboxPolicy(kTestPolicyId, policy); | 436 sandbox_->RegisterSandboxPolicy(kTestPolicyId, policy); |
| 437 | 437 |
| 438 // Launch the child. | 438 // Launch the child. |
| 439 sandbox_->PrepareToForkWithPolicy(kTestPolicyId); | 439 sandbox_->PrepareToForkWithPolicy(kTestPolicyId); |
| 440 base::LaunchOptions options; | 440 base::LaunchOptions options; |
| 441 options.replacement_bootstrap_name = sandbox_->server_bootstrap_name(); | 441 options.replacement_bootstrap_name = sandbox_->server_bootstrap_name(); |
| 442 base::ProcessHandle pid = | 442 base::Process process = SpawnChildWithOptions("ChildOutliveSandbox", options); |
| 443 SpawnChildWithOptions("ChildOutliveSandbox", options); | 443 ASSERT_TRUE(process.IsValid()); |
| 444 ASSERT_GT(pid, 0); | 444 sandbox_->FinishedFork(process.Handle()); |
| 445 sandbox_->FinishedFork(pid); | |
| 446 | 445 |
| 447 // Synchronize with the child. | 446 // Synchronize with the child. |
| 448 mach_msg_empty_rcv_t rcv_msg; | 447 mach_msg_empty_rcv_t rcv_msg; |
| 449 bzero(&rcv_msg, sizeof(rcv_msg)); | 448 bzero(&rcv_msg, sizeof(rcv_msg)); |
| 450 kern_return_t kr = mach_msg(&rcv_msg.header, MACH_RCV_MSG, 0, | 449 kern_return_t kr = mach_msg(&rcv_msg.header, MACH_RCV_MSG, 0, |
| 451 sizeof(rcv_msg), port, | 450 sizeof(rcv_msg), port, |
| 452 TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL); | 451 TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL); |
| 453 ASSERT_EQ(KERN_SUCCESS, kr) << mach_error_string(kr); | 452 ASSERT_EQ(KERN_SUCCESS, kr) << mach_error_string(kr); |
| 454 | 453 |
| 455 // Destroy the sandbox. | 454 // Destroy the sandbox. |
| 456 sandbox_.reset(); | 455 sandbox_.reset(); |
| 457 | 456 |
| 458 // Synchronize again with the child. | 457 // Synchronize again with the child. |
| 459 mach_msg_empty_send_t send_msg; | 458 mach_msg_empty_send_t send_msg; |
| 460 bzero(&send_msg, sizeof(send_msg)); | 459 bzero(&send_msg, sizeof(send_msg)); |
| 461 send_msg.header.msgh_size = sizeof(send_msg); | 460 send_msg.header.msgh_size = sizeof(send_msg); |
| 462 send_msg.header.msgh_remote_port = rcv_msg.header.msgh_remote_port; | 461 send_msg.header.msgh_remote_port = rcv_msg.header.msgh_remote_port; |
| 463 send_msg.header.msgh_bits = | 462 send_msg.header.msgh_bits = |
| 464 MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE); | 463 MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE); |
| 465 kr = mach_msg(&send_msg.header, MACH_SEND_MSG, send_msg.header.msgh_size, 0, | 464 kr = mach_msg(&send_msg.header, MACH_SEND_MSG, send_msg.header.msgh_size, 0, |
| 466 MACH_PORT_NULL, TestTimeouts::tiny_timeout().InMilliseconds(), | 465 MACH_PORT_NULL, TestTimeouts::tiny_timeout().InMilliseconds(), |
| 467 MACH_PORT_NULL); | 466 MACH_PORT_NULL); |
| 468 EXPECT_EQ(KERN_SUCCESS, kr) << mach_error_string(kr); | 467 EXPECT_EQ(KERN_SUCCESS, kr) << mach_error_string(kr); |
| 469 | 468 |
| 470 int code = 0; | 469 int code = 0; |
| 471 EXPECT_TRUE(base::WaitForExitCode(pid, &code)); | 470 EXPECT_TRUE(process.WaitForExit(&code)); |
| 472 EXPECT_EQ(0, code); | 471 EXPECT_EQ(0, code); |
| 473 } | 472 } |
| 474 | 473 |
| 475 MULTIPROCESS_TEST_MAIN(ChildOutliveSandbox) { | 474 MULTIPROCESS_TEST_MAIN(ChildOutliveSandbox) { |
| 476 // Get the synchronization channel. | 475 // Get the synchronization channel. |
| 477 mach_port_t port = MACH_PORT_NULL; | 476 mach_port_t port = MACH_PORT_NULL; |
| 478 CHECK_EQ(KERN_SUCCESS, bootstrap_look_up(bootstrap_port, "sync", &port)); | 477 CHECK_EQ(KERN_SUCCESS, bootstrap_look_up(bootstrap_port, "sync", &port)); |
| 479 | 478 |
| 480 // Create a reply port. | 479 // Create a reply port. |
| 481 mach_port_t reply_port; | 480 mach_port_t reply_port; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 510 kr = mach_msg_receive(&rcv_msg.header); | 509 kr = mach_msg_receive(&rcv_msg.header); |
| 511 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg_receive"; | 510 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg_receive"; |
| 512 | 511 |
| 513 // Try to message the sandbox. | 512 // Try to message the sandbox. |
| 514 bootstrap_look_up(bootstrap_port, "test", &port); | 513 bootstrap_look_up(bootstrap_port, "test", &port); |
| 515 | 514 |
| 516 return 0; | 515 return 0; |
| 517 } | 516 } |
| 518 | 517 |
| 519 } // namespace sandbox | 518 } // namespace sandbox |
| OLD | NEW |