diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-04 00:10:25 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-04 00:10:25 +0000 |
commit | 97538a1abd5e3988c9acefd0d09b29caeffb0e28 (patch) | |
tree | 68814e2722ca1e7c273ea57aa207fb59f983d6cd /sandbox | |
parent | 6575c42bc5685b0ce35067a94d0b84e1606037a7 (diff) | |
download | chromium_src-97538a1abd5e3988c9acefd0d09b29caeffb0e28.zip chromium_src-97538a1abd5e3988c9acefd0d09b29caeffb0e28.tar.gz chromium_src-97538a1abd5e3988c9acefd0d09b29caeffb0e28.tar.bz2 |
Make BootstrapSandboxPolicy a struct, containing the existing rule map and a new default rule.
The default rule will be used to specify the action to take when the requested
name does not have an entry in the rule map.
BUG=367863
R=mark@chromium.org
Review URL: https://codereview.chromium.org/310833003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274676 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/mac/bootstrap_sandbox_unittest.mm | 88 | ||||
-rw-r--r-- | sandbox/mac/launchd_interception_server.cc | 8 | ||||
-rw-r--r-- | sandbox/mac/policy.cc | 40 | ||||
-rw-r--r-- | sandbox/mac/policy.h | 16 | ||||
-rw-r--r-- | sandbox/mac/policy_unittest.cc | 54 |
5 files changed, 169 insertions, 37 deletions
diff --git a/sandbox/mac/bootstrap_sandbox_unittest.mm b/sandbox/mac/bootstrap_sandbox_unittest.mm index f8d8165b..f9068d6 100644 --- a/sandbox/mac/bootstrap_sandbox_unittest.mm +++ b/sandbox/mac/bootstrap_sandbox_unittest.mm @@ -88,7 +88,7 @@ class BootstrapSandboxTest : public base::MultiProcessTest { BootstrapSandboxPolicy BaselinePolicy() { BootstrapSandboxPolicy policy; if (base::mac::IsOSSnowLeopard()) - policy["com.apple.SecurityServer"] = Rule(POLICY_ALLOW); + policy.rules["com.apple.SecurityServer"] = Rule(POLICY_ALLOW); return policy; } @@ -149,11 +149,11 @@ TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxAllow) { BootstrapSandboxPolicy policy(BaselinePolicy()); // 10.9: - policy["com.apple.distributed_notifications@Uv3"] = Rule(POLICY_ALLOW); - policy["com.apple.distributed_notifications@1v3"] = Rule(POLICY_ALLOW); + policy.rules["com.apple.distributed_notifications@Uv3"] = Rule(POLICY_ALLOW); + policy.rules["com.apple.distributed_notifications@1v3"] = Rule(POLICY_ALLOW); // 10.6: - policy["com.apple.system.notification_center"] = Rule(POLICY_ALLOW); - policy["com.apple.distributed_notifications.2"] = Rule(POLICY_ALLOW); + policy.rules["com.apple.system.notification_center"] = Rule(POLICY_ALLOW); + policy.rules["com.apple.distributed_notifications.2"] = Rule(POLICY_ALLOW); sandbox_->RegisterSandboxPolicy(2, policy); base::ProcessHandle pid; @@ -175,7 +175,7 @@ const char kTestServer[] = "org.chromium.test_bootstrap_server"; TEST_F(BootstrapSandboxTest, PolicyDenyError) { BootstrapSandboxPolicy policy(BaselinePolicy()); - policy[kTestServer] = Rule(POLICY_DENY_ERROR); + policy.rules[kTestServer] = Rule(POLICY_DENY_ERROR); sandbox_->RegisterSandboxPolicy(1, policy); RunChildWithPolicy(1, "PolicyDenyError", NULL); @@ -198,7 +198,7 @@ MULTIPROCESS_TEST_MAIN(PolicyDenyError) { TEST_F(BootstrapSandboxTest, PolicyDenyDummyPort) { BootstrapSandboxPolicy policy(BaselinePolicy()); - policy[kTestServer] = Rule(POLICY_DENY_DUMMY_PORT); + policy.rules[kTestServer] = Rule(POLICY_DENY_DUMMY_PORT); sandbox_->RegisterSandboxPolicy(1, policy); RunChildWithPolicy(1, "PolicyDenyDummyPort", NULL); @@ -247,7 +247,7 @@ TEST_F(BootstrapSandboxTest, PolicySubstitutePort) { EXPECT_EQ(1u, send_rights); BootstrapSandboxPolicy policy(BaselinePolicy()); - policy[kTestServer] = Rule(port); + policy.rules[kTestServer] = Rule(port); sandbox_->RegisterSandboxPolicy(1, policy); RunChildWithPolicy(1, "PolicySubstitutePort", NULL); @@ -340,4 +340,76 @@ TEST_F(BootstrapSandboxTest, ForwardMessageInProcess) { EXPECT_EQ(2u, send_rights); } +const char kDefaultRuleTestAllow[] = + "org.chromium.sandbox.test.DefaultRuleAllow"; +const char kDefaultRuleTestDeny[] = + "org.chromium.sandbox.test.DefaultRuleAllow.Deny"; + +TEST_F(BootstrapSandboxTest, DefaultRuleAllow) { + mach_port_t task = mach_task_self(); + + mach_port_t port; + ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, + &port)); + base::mac::ScopedMachReceiveRight scoped_port_recv(port); + + ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(task, port, port, + MACH_MSG_TYPE_MAKE_SEND)); + base::mac::ScopedMachSendRight scoped_port_send(port); + + BootstrapSandboxPolicy policy; + policy.default_rule = Rule(POLICY_ALLOW); + policy.rules[kDefaultRuleTestAllow] = Rule(port); + policy.rules[kDefaultRuleTestDeny] = Rule(POLICY_DENY_ERROR); + sandbox_->RegisterSandboxPolicy(3, policy); + + base::scoped_nsobject<DistributedNotificationObserver> observer( + [[DistributedNotificationObserver alloc] init]); + + int pid = 0; + RunChildWithPolicy(3, "DefaultRuleAllow", &pid); + EXPECT_GT(pid, 0); + + [observer waitForNotification]; + EXPECT_EQ(1, [observer receivedCount]); + EXPECT_EQ(pid, [[observer object] intValue]); + + struct SubstitutePortAckRecv msg; + bzero(&msg, sizeof(msg)); + msg.header.msgh_size = sizeof(msg); + msg.header.msgh_local_port = port; + kern_return_t kr = mach_msg(&msg.header, MACH_RCV_MSG, 0, + msg.header.msgh_size, port, + TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL); + EXPECT_EQ(KERN_SUCCESS, kr); + + EXPECT_EQ(0, strncmp(kSubstituteAck, msg.buf, sizeof(msg.buf))); +} + +MULTIPROCESS_TEST_MAIN(DefaultRuleAllow) { + [[NSDistributedNotificationCenter defaultCenter] + postNotificationName:kTestNotification + object:[NSString stringWithFormat:@"%d", getpid()]]; + + mach_port_t port = MACH_PORT_NULL; + CHECK_EQ(BOOTSTRAP_UNKNOWN_SERVICE, bootstrap_look_up(bootstrap_port, + const_cast<char*>(kDefaultRuleTestDeny), &port)); + CHECK(port == MACH_PORT_NULL); + + CHECK_EQ(KERN_SUCCESS, bootstrap_look_up(bootstrap_port, + const_cast<char*>(kDefaultRuleTestAllow), &port)); + CHECK(port != MACH_PORT_NULL); + + struct SubstitutePortAckSend msg; + bzero(&msg, sizeof(msg)); + msg.header.msgh_size = sizeof(msg); + msg.header.msgh_remote_port = port; + msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND); + strncpy(msg.buf, kSubstituteAck, sizeof(msg.buf)); + + CHECK_EQ(KERN_SUCCESS, mach_msg_send(&msg.header)); + + return 0; +} + } // namespace sandbox diff --git a/sandbox/mac/launchd_interception_server.cc b/sandbox/mac/launchd_interception_server.cc index 3cb1821..57264aa 100644 --- a/sandbox/mac/launchd_interception_server.cc +++ b/sandbox/mac/launchd_interception_server.cc @@ -191,10 +191,10 @@ void LaunchdInterceptionServer::HandleLookUp(mach_msg_header_t* request, // Find the Rule for this service. If one is not found, use // a safe default, POLICY_DENY_ERROR. const BootstrapSandboxPolicy* policy = sandbox_->PolicyForProcess(sender_pid); - const BootstrapSandboxPolicy::const_iterator it = - policy->find(request_service_name); - Rule rule(POLICY_DENY_ERROR); - if (it != policy->end()) + const BootstrapSandboxPolicy::NamedRules::const_iterator it = + policy->rules.find(request_service_name); + Rule rule(policy->default_rule); + if (it != policy->rules.end()) rule = it->second; if (rule.result == POLICY_ALLOW) { diff --git a/sandbox/mac/policy.cc b/sandbox/mac/policy.cc index 5493c28..293255a 100644 --- a/sandbox/mac/policy.cc +++ b/sandbox/mac/policy.cc @@ -21,22 +21,34 @@ Rule::Rule(mach_port_t override_port) substitute_port(override_port) { } +BootstrapSandboxPolicy::BootstrapSandboxPolicy() + : default_rule(POLICY_DENY_ERROR) { +} + +BootstrapSandboxPolicy::~BootstrapSandboxPolicy() {} + +static bool IsRuleValid(const Rule& rule) { + if (!(rule.result > POLICY_DECISION_INVALID && + rule.result < POLICY_DECISION_LAST)) { + return false; + } + if (rule.result == POLICY_SUBSTITUTE_PORT) { + if (rule.substitute_port == MACH_PORT_NULL) + return false; + } else { + if (rule.substitute_port != MACH_PORT_NULL) + return false; + } + return true; +} + bool IsPolicyValid(const BootstrapSandboxPolicy& policy) { - for (BootstrapSandboxPolicy::const_iterator it = policy.begin(); - it != policy.end(); - ++it) { - const Rule& rule = it->second; - if (!(rule.result > POLICY_DECISION_INVALID && - rule.result < POLICY_DECISION_LAST)) { + if (!IsRuleValid(policy.default_rule)) + return false; + + for (const auto& pair : policy.rules) { + if (!IsRuleValid(pair.second)) return false; - } - if (rule.result == POLICY_SUBSTITUTE_PORT) { - if (rule.substitute_port == MACH_PORT_NULL) - return false; - } else { - if (rule.substitute_port != MACH_PORT_NULL) - return false; - } } return true; } diff --git a/sandbox/mac/policy.h b/sandbox/mac/policy.h index 0cedcb8..e500468 100644 --- a/sandbox/mac/policy.h +++ b/sandbox/mac/policy.h @@ -47,8 +47,20 @@ struct SANDBOX_EXPORT Rule { mach_port_t substitute_port; }; -// A SandboxPolicy maps bootstrap server names to policy Rules. -typedef std::map<std::string, Rule> BootstrapSandboxPolicy; +// A policy object manages the rules enforced on a target sandboxed process. +struct SANDBOX_EXPORT BootstrapSandboxPolicy { + typedef std::map<std::string, Rule> NamedRules; + + BootstrapSandboxPolicy(); + ~BootstrapSandboxPolicy(); + + // The default action to take if the server name being looked up is not + // present in |rules|. + Rule default_rule; + + // A map of bootstrap server names to policy Rules. + NamedRules rules; +}; // Checks that a policy is well-formed. SANDBOX_EXPORT bool IsPolicyValid(const BootstrapSandboxPolicy& policy); diff --git a/sandbox/mac/policy_unittest.cc b/sandbox/mac/policy_unittest.cc index d019fdd..54e0e74 100644 --- a/sandbox/mac/policy_unittest.cc +++ b/sandbox/mac/policy_unittest.cc @@ -14,24 +14,24 @@ TEST(PolicyTest, ValidEmptyPolicy) { TEST(PolicyTest, ValidPolicy) { BootstrapSandboxPolicy policy; - policy["allow"] = Rule(POLICY_ALLOW); - policy["deny_error"] = Rule(POLICY_DENY_ERROR); - policy["deny_dummy"] = Rule(POLICY_DENY_DUMMY_PORT); - policy["substitue"] = Rule(mach_task_self()); + policy.rules["allow"] = Rule(POLICY_ALLOW); + policy.rules["deny_error"] = Rule(POLICY_DENY_ERROR); + policy.rules["deny_dummy"] = Rule(POLICY_DENY_DUMMY_PORT); + policy.rules["substitue"] = Rule(mach_task_self()); EXPECT_TRUE(IsPolicyValid(policy)); } TEST(PolicyTest, InvalidPolicyEmptyRule) { Rule rule; BootstrapSandboxPolicy policy; - policy["test"] = rule; + policy.rules["test"] = rule; EXPECT_FALSE(IsPolicyValid(policy)); } TEST(PolicyTest, InvalidPolicySubstitue) { Rule rule(POLICY_SUBSTITUTE_PORT); BootstrapSandboxPolicy policy; - policy["test"] = rule; + policy.rules["test"] = rule; EXPECT_FALSE(IsPolicyValid(policy)); } @@ -39,7 +39,7 @@ TEST(PolicyTest, InvalidPolicyWithPortAllow) { Rule rule(POLICY_ALLOW); rule.substitute_port = mach_task_self(); BootstrapSandboxPolicy policy; - policy["allow"] = rule; + policy.rules["allow"] = rule; EXPECT_FALSE(IsPolicyValid(policy)); } @@ -47,7 +47,7 @@ TEST(PolicyTest, InvalidPolicyWithPortDenyError) { Rule rule(POLICY_DENY_ERROR); rule.substitute_port = mach_task_self(); BootstrapSandboxPolicy policy; - policy["deny_error"] = rule; + policy.rules["deny_error"] = rule; EXPECT_FALSE(IsPolicyValid(policy)); } @@ -55,7 +55,43 @@ TEST(PolicyTest, InvalidPolicyWithPortDummy) { Rule rule(POLICY_DENY_DUMMY_PORT); rule.substitute_port = mach_task_self(); BootstrapSandboxPolicy policy; - policy["deny_dummy"] = rule; + policy.rules["deny_dummy"] = rule; + EXPECT_FALSE(IsPolicyValid(policy)); +} + +TEST(PolicyTest, InvalidPolicyDefaultRule) { + BootstrapSandboxPolicy policy; + policy.default_rule = Rule(); + EXPECT_FALSE(IsPolicyValid(policy)); +} + +TEST(PolicyTest, InvalidPolicyDefaultRuleSubstitue) { + BootstrapSandboxPolicy policy; + policy.default_rule = Rule(POLICY_SUBSTITUTE_PORT); + EXPECT_FALSE(IsPolicyValid(policy)); +} + +TEST(PolicyTest, InvalidPolicyDefaultRuleWithPortAllow) { + Rule rule(POLICY_ALLOW); + rule.substitute_port = mach_task_self(); + BootstrapSandboxPolicy policy; + policy.default_rule = rule; + EXPECT_FALSE(IsPolicyValid(policy)); +} + +TEST(PolicyTest, InvalidPolicyDefaultRuleWithPortDenyError) { + Rule rule(POLICY_DENY_ERROR); + rule.substitute_port = mach_task_self(); + BootstrapSandboxPolicy policy; + policy.default_rule = rule; + EXPECT_FALSE(IsPolicyValid(policy)); +} + +TEST(PolicyTest, InvalidPolicyDefaultRuleWithPortDummy) { + Rule rule(POLICY_DENY_DUMMY_PORT); + rule.substitute_port = mach_task_self(); + BootstrapSandboxPolicy policy; + policy.default_rule = rule; EXPECT_FALSE(IsPolicyValid(policy)); } |