summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-04 00:10:25 +0000
committerrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-04 00:10:25 +0000
commit97538a1abd5e3988c9acefd0d09b29caeffb0e28 (patch)
tree68814e2722ca1e7c273ea57aa207fb59f983d6cd /sandbox
parent6575c42bc5685b0ce35067a94d0b84e1606037a7 (diff)
downloadchromium_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.mm88
-rw-r--r--sandbox/mac/launchd_interception_server.cc8
-rw-r--r--sandbox/mac/policy.cc40
-rw-r--r--sandbox/mac/policy.h16
-rw-r--r--sandbox/mac/policy_unittest.cc54
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));
}