Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: sandbox/mac/bootstrap_sandbox_unittest.mm

Issue 264923003: Initial implementation of the Mac Bootstrap Sandbox. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase for sandbox_export.h Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/mac/bootstrap_sandbox.cc ('k') | sandbox/mac/launchd_interception_server.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/mac/bootstrap_sandbox.h"
6
7 #include <CoreFoundation/CoreFoundation.h>
8 #import <Foundation/Foundation.h>
9 #include <mach/mach.h>
10 #include <servers/bootstrap.h>
11
12 #include "base/logging.h"
13 #include "base/mac/mac_util.h"
14 #include "base/mac/scoped_nsobject.h"
15 #include "base/mac/scoped_mach_port.h"
16 #include "base/process/kill.h"
17 #include "base/test/multiprocess_test.h"
18 #include "base/test/test_timeouts.h"
19 #import "testing/gtest_mac.h"
20 #include "testing/multiprocess_func_list.h"
21
22 NSString* const kTestNotification = @"org.chromium.bootstrap_sandbox_test";
23
24 @interface DistributedNotificationObserver : NSObject {
25 @private
26 int receivedCount_;
27 base::scoped_nsobject<NSString> object_;
28 }
29 - (int)receivedCount;
30 - (NSString*)object;
31 - (void)waitForNotification;
32 @end
33
34 @implementation DistributedNotificationObserver
35 - (id)init {
36 if ((self = [super init])) {
37 [[NSDistributedNotificationCenter defaultCenter]
38 addObserver:self
39 selector:@selector(observeNotification:)
40 name:kTestNotification
41 object:nil];
42 }
43 return self;
44 }
45
46 - (void)dealloc {
47 [[NSDistributedNotificationCenter defaultCenter]
48 removeObserver:self
49 name:kTestNotification
50 object:nil];
51 [super dealloc];
52 }
53
54 - (int)receivedCount {
55 return receivedCount_;
56 }
57
58 - (NSString*)object {
59 return object_.get();
60 }
61
62 - (void)waitForNotification {
63 object_.reset();
64 CFRunLoopRunInMode(kCFRunLoopDefaultMode,
65 TestTimeouts::action_timeout().InSeconds(), false);
66 }
67
68 - (void)observeNotification:(NSNotification*)notification {
69 ++receivedCount_;
70 object_.reset([[notification object] copy]);
71 CFRunLoopStop(CFRunLoopGetCurrent());
72 }
73 @end
74
75 ////////////////////////////////////////////////////////////////////////////////
76
77 namespace sandbox {
78
79 class BootstrapSandboxTest : public base::MultiProcessTest {
80 public:
81 virtual void SetUp() OVERRIDE {
82 base::MultiProcessTest::SetUp();
83
84 sandbox_ = BootstrapSandbox::Create();
85 ASSERT_TRUE(sandbox_.get());
86 }
87
88 BootstrapSandboxPolicy BaselinePolicy() {
89 BootstrapSandboxPolicy policy;
90 if (base::mac::IsOSSnowLeopard())
91 policy["com.apple.SecurityServer"] = Rule(POLICY_ALLOW);
92 return policy;
93 }
94
95 void RunChildWithPolicy(int policy_id,
96 const char* child_name,
97 base::ProcessHandle* out_pid) {
98 sandbox_->PrepareToForkWithPolicy(policy_id);
99 base::ProcessHandle pid = SpawnChild(child_name);
100 ASSERT_GT(pid, 0);
101 sandbox_->FinishedFork(pid);
102 int code = 0;
103 EXPECT_TRUE(base::WaitForExitCode(pid, &code));
104 EXPECT_EQ(0, code);
105 if (out_pid)
106 *out_pid = pid;
107 }
108
109 protected:
110 scoped_ptr<BootstrapSandbox> sandbox_;
111 };
112
113 const char kNotificationTestMain[] = "PostNotification";
114
115 // Run the test without the sandbox.
116 TEST_F(BootstrapSandboxTest, DistributedNotifications_Unsandboxed) {
117 base::scoped_nsobject<DistributedNotificationObserver> observer(
118 [[DistributedNotificationObserver alloc] init]);
119
120 base::ProcessHandle pid = SpawnChild(kNotificationTestMain);
121 ASSERT_GT(pid, 0);
122 int code = 0;
123 EXPECT_TRUE(base::WaitForExitCode(pid, &code));
124 EXPECT_EQ(0, code);
125
126 [observer waitForNotification];
127 EXPECT_EQ(1, [observer receivedCount]);
128 EXPECT_EQ(pid, [[observer object] intValue]);
129 }
130
131 // Run the test with the sandbox enabled without notifications on the policy
132 // whitelist.
133 TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxDeny) {
134 base::scoped_nsobject<DistributedNotificationObserver> observer(
135 [[DistributedNotificationObserver alloc] init]);
136
137 sandbox_->RegisterSandboxPolicy(1, BaselinePolicy());
138 RunChildWithPolicy(1, kNotificationTestMain, NULL);
139
140 [observer waitForNotification];
141 EXPECT_EQ(0, [observer receivedCount]);
142 EXPECT_EQ(nil, [observer object]);
143 }
144
145 // Run the test with notifications permitted.
146 TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxAllow) {
147 base::scoped_nsobject<DistributedNotificationObserver> observer(
148 [[DistributedNotificationObserver alloc] init]);
149
150 BootstrapSandboxPolicy policy(BaselinePolicy());
151 // 10.9:
152 policy["com.apple.distributed_notifications@Uv3"] = Rule(POLICY_ALLOW);
153 policy["com.apple.distributed_notifications@1v3"] = Rule(POLICY_ALLOW);
154 // 10.6:
155 policy["com.apple.system.notification_center"] = Rule(POLICY_ALLOW);
156 policy["com.apple.distributed_notifications.2"] = Rule(POLICY_ALLOW);
157 sandbox_->RegisterSandboxPolicy(2, policy);
158
159 base::ProcessHandle pid;
160 RunChildWithPolicy(2, kNotificationTestMain, &pid);
161
162 [observer waitForNotification];
163 EXPECT_EQ(1, [observer receivedCount]);
164 EXPECT_EQ(pid, [[observer object] intValue]);
165 }
166
167 MULTIPROCESS_TEST_MAIN(PostNotification) {
168 [[NSDistributedNotificationCenter defaultCenter]
169 postNotificationName:kTestNotification
170 object:[NSString stringWithFormat:@"%d", getpid()]];
171 return 0;
172 }
173
174 const char kTestServer[] = "org.chromium.test_bootstrap_server";
175
176 TEST_F(BootstrapSandboxTest, PolicyDenyError) {
177 BootstrapSandboxPolicy policy(BaselinePolicy());
178 policy[kTestServer] = Rule(POLICY_DENY_ERROR);
179 sandbox_->RegisterSandboxPolicy(1, policy);
180
181 RunChildWithPolicy(1, "PolicyDenyError", NULL);
182 }
183
184 MULTIPROCESS_TEST_MAIN(PolicyDenyError) {
185 mach_port_t port = MACH_PORT_NULL;
186 kern_return_t kr = bootstrap_look_up(bootstrap_port, kTestServer,
187 &port);
188 CHECK_EQ(BOOTSTRAP_UNKNOWN_SERVICE, kr);
189 CHECK(port == MACH_PORT_NULL);
190
191 kr = bootstrap_look_up(bootstrap_port, "org.chromium.some_other_server",
192 &port);
193 CHECK_EQ(BOOTSTRAP_UNKNOWN_SERVICE, kr);
194 CHECK(port == MACH_PORT_NULL);
195
196 return 0;
197 }
198
199 TEST_F(BootstrapSandboxTest, PolicyDenyDummyPort) {
200 BootstrapSandboxPolicy policy(BaselinePolicy());
201 policy[kTestServer] = Rule(POLICY_DENY_DUMMY_PORT);
202 sandbox_->RegisterSandboxPolicy(1, policy);
203
204 RunChildWithPolicy(1, "PolicyDenyDummyPort", NULL);
205 }
206
207 MULTIPROCESS_TEST_MAIN(PolicyDenyDummyPort) {
208 mach_port_t port = MACH_PORT_NULL;
209 kern_return_t kr = bootstrap_look_up(bootstrap_port, kTestServer,
210 &port);
211 CHECK_EQ(KERN_SUCCESS, kr);
212 CHECK(port != MACH_PORT_NULL);
213 return 0;
214 }
215
216 struct SubstitutePortAckSend {
217 mach_msg_header_t header;
218 char buf[32];
219 };
220
221 struct SubstitutePortAckRecv : public SubstitutePortAckSend {
222 mach_msg_trailer_t trailer;
223 };
224
225 const char kSubstituteAck[] = "Hello, this is doge!";
226
227 TEST_F(BootstrapSandboxTest, PolicySubstitutePort) {
228 mach_port_t port;
229 ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(mach_task_self(),
230 MACH_PORT_RIGHT_RECEIVE, &port));
231 base::mac::ScopedMachPort scoped_port(port);
232
233 BootstrapSandboxPolicy policy(BaselinePolicy());
234 policy[kTestServer] = Rule(port);
235 sandbox_->RegisterSandboxPolicy(1, policy);
236
237 RunChildWithPolicy(1, "PolicySubstitutePort", NULL);
238
239 struct SubstitutePortAckRecv msg;
240 bzero(&msg, sizeof(msg));
241 msg.header.msgh_size = sizeof(msg);
242 msg.header.msgh_local_port = port;
243 kern_return_t kr = mach_msg(&msg.header, MACH_RCV_MSG, 0,
244 msg.header.msgh_size, port,
245 TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL);
246 EXPECT_EQ(KERN_SUCCESS, kr);
247
248 EXPECT_EQ(0, strncmp(kSubstituteAck, msg.buf, sizeof(msg.buf)));
249 }
250
251 MULTIPROCESS_TEST_MAIN(PolicySubstitutePort) {
252 mach_port_t port = MACH_PORT_NULL;
253 kern_return_t kr = bootstrap_look_up(bootstrap_port, kTestServer, &port);
254 CHECK_EQ(KERN_SUCCESS, kr);
255 CHECK(port != MACH_PORT_NULL);
256
257 struct SubstitutePortAckSend msg;
258 bzero(&msg, sizeof(msg));
259 msg.header.msgh_size = sizeof(msg);
260 msg.header.msgh_remote_port = port;
261 msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND);
262 strncpy(msg.buf, kSubstituteAck, sizeof(msg.buf));
263
264 CHECK_EQ(KERN_SUCCESS, mach_msg_send(&msg.header));
265
266 return 0;
267 }
268
269 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/mac/bootstrap_sandbox.cc ('k') | sandbox/mac/launchd_interception_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698