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

Side by Side Diff: content/common/sandbox_win_unittest.cc

Issue 1750793002: Delete content sandbox tests which exercise handle inheritance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « no previous file | content/content_tests.gypi » ('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 2016 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 "base/base_switches.h"
6 #include "base/command_line.h"
7 #include "base/files/file_path.h"
8 #include "base/lazy_instance.h"
9 #include "base/rand_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/test/multiprocess_test.h"
13 #include "base/win/win_util.h"
14 #include "content/public/common/sandbox_init.h"
15 #include "content/public/common/sandboxed_process_launcher_delegate.h"
16 #include "sandbox/win/src/sandbox_factory.h"
17 #include "sandbox/win/src/security_level.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/multiprocess_func_list.h"
20
21 namespace content {
22 namespace {
23
24 const size_t kMaxMessageLength = 64;
25 const char kTestMessage1Switch[] = "sandbox-test-message-1";
26 const char kTestMessage2Switch[] = "sandbox-test-message-2";
27 const char kInheritedHandle1Switch[] = "inherited-handle-1";
28 const char kInheritedHandle2Switch[] = "inherited-handle-2";
29
30 void InitializeTestSandbox() {
31 sandbox::SandboxInterfaceInfo info = {0};
32 info.broker_services = sandbox::SandboxFactory::GetBrokerServices();
33 if (!info.broker_services)
34 info.target_services = sandbox::SandboxFactory::GetTargetServices();
35 CHECK(info.broker_services || info.target_services);
36 CHECK(InitializeSandbox(&info));
37 }
38
39 class SandboxInitializer {
40 public:
41 SandboxInitializer() { InitializeTestSandbox(); }
42 };
43
44 base::LazyInstance<SandboxInitializer> g_sandbox_initializer;
45
46 HANDLE GetHandleFromCommandLine(const char* switch_name) {
47 unsigned handle_id;
48 CHECK(base::StringToUint(
49 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name),
50 &handle_id));
51 CHECK(handle_id);
52 return reinterpret_cast<HANDLE>(handle_id);
53 }
54
55 std::string ReadMessageFromPipe(HANDLE pipe) {
56 char buffer[kMaxMessageLength];
57 DWORD bytes_read = 0;
58 BOOL result =
59 ::ReadFile(pipe, buffer, kMaxMessageLength, &bytes_read, nullptr);
60 PCHECK(result);
61 return std::string(buffer, bytes_read);
62 }
63
64 void WriteMessageToPipe(HANDLE pipe, const base::StringPiece& message) {
65 DWORD bytes_written = 0;
66 BOOL result = ::WriteFile(pipe, message.data(), message.size(),
67 &bytes_written, nullptr);
68 CHECK_EQ(message.size(), static_cast<size_t>(bytes_written));
69 PCHECK(result);
70 }
71
72 // Does what MultiProcessTest::MakeCmdLine does, plus ensures ".exe" extension
73 // on Program.
74 base::CommandLine MakeCmdLineWithExtension(const std::string& testTarget) {
75 base::CommandLine cmd_line = base::GetMultiProcessTestChildBaseCommandLine();
76 cmd_line.AppendSwitchASCII(switches::kTestChildProcess, testTarget);
77
78 base::FilePath program = cmd_line.GetProgram();
79 cmd_line.SetProgram(program.ReplaceExtension(L"exe"));
80 return cmd_line;
81 }
82
83 class SandboxWinTest : public base::MultiProcessTest {
84 public:
85 SandboxWinTest() {}
86 ~SandboxWinTest() override {}
87
88 void SetUp() override {
89 // Ensure the sandbox broker services are initialized exactly once in the
90 // parent test process.
91 g_sandbox_initializer.Get();
92 }
93
94 protected:
95 // Creates a new pipe for synchronous IO. The client handle is created in a
96 // non-inheritable state.
97 void CreatePipe(base::win::ScopedHandle* server,
98 base::win::ScopedHandle* client) {
99 std::string pipe_name = base::StringPrintf(
100 "\\\\.\\pipe\\sandbox_win_test.%I64u", base::RandUint64());
101 server->Set(CreateNamedPipeA(
102 pipe_name.c_str(), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
103 FILE_FLAG_FIRST_PIPE_INSTANCE,
104 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, 4096, 4096, 5000, nullptr));
105 CHECK(server->IsValid());
106
107 client->Set(CreateFileA(
108 pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
109 OPEN_EXISTING, SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS, nullptr));
110 CHECK(client->IsValid());
111 }
112
113 base::Process LaunchTestClient(
114 base::CommandLine* cmd_line,
115 bool sandboxed,
116 const base::HandlesToInheritVector& handles_to_inherit) {
117 TestLauncherDelegate delegate(sandboxed);
118 base::Process process = StartSandboxedProcess(
119 &delegate, cmd_line, handles_to_inherit);
120 CHECK(process.IsValid());
121 return process;
122 }
123
124 class TestLauncherDelegate : public SandboxedProcessLauncherDelegate {
125 public:
126 explicit TestLauncherDelegate(bool should_sandbox)
127 : should_sandbox_(should_sandbox) {}
128 ~TestLauncherDelegate() override {}
129
130 // SandboxedProcessLauncherDelegate:
131 bool ShouldSandbox() override { return should_sandbox_; }
132
133 bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
134 policy->SetTokenLevel(sandbox::USER_INTERACTIVE, sandbox::USER_LOCKDOWN);
135 return true;
136 }
137
138 SandboxType GetSandboxType() override { return SANDBOX_TYPE_RENDERER; }
139
140 private:
141 bool should_sandbox_;
142 };
143 };
144
145 // -----------------------------------------------------------------------------
146 // Tests follow: single-handle inheritance.
147 // -----------------------------------------------------------------------------
148
149 MULTIPROCESS_TEST_MAIN(ReadPipe) {
150 InitializeTestSandbox();
151
152 // Expects a message and pipe handle to be passed in, and expects to read the
153 // same message from that pipe. Exits with 0 on success, 1 on failure.
154
155 base::win::ScopedHandle pipe(
156 GetHandleFromCommandLine(kInheritedHandle1Switch));
157 std::string message = ReadMessageFromPipe(pipe.Get());
158
159 if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
160 kTestMessage1Switch) != message) {
161 return 1;
162 }
163
164 return 0;
165 }
166
167 TEST_F(SandboxWinTest, InheritSingleHandleUnsandboxed) {
168 base::CommandLine cmd_line = MakeCmdLineWithExtension("ReadPipe");
169
170 base::win::ScopedHandle server, client;
171 CreatePipe(&server, &client);
172
173 base::HandlesToInheritVector handles;
174 handles.push_back(client.Get());
175
176 // Pass a test message and the pipe handle ID on the command line.
177 const std::string kTestMessage = "Hello, world!";
178 cmd_line.AppendSwitchASCII(kTestMessage1Switch, kTestMessage);
179 cmd_line.AppendSwitchASCII(
180 kInheritedHandle1Switch,
181 base::UintToString(base::win::HandleToUint32(client.Get())));
182
183 base::Process child_process =
184 LaunchTestClient(&cmd_line, false /* sandboxed */, handles);
185
186 WriteMessageToPipe(server.Get(), kTestMessage);
187
188 int exit_code = 0;
189 child_process.WaitForExit(&exit_code);
190 EXPECT_EQ(0, exit_code);
191 }
192
193 TEST_F(SandboxWinTest, InheritSingleHandleSandboxed) {
194 base::CommandLine cmd_line = MakeCmdLineWithExtension("ReadPipe");
195
196 base::win::ScopedHandle server, client;
197 CreatePipe(&server, &client);
198
199 base::HandlesToInheritVector handles;
200 handles.push_back(client.Get());
201
202 // Pass a test message and the pipe handle ID on the command line.
203 const std::string kTestMessage = "Hello, world!";
204 cmd_line.AppendSwitchASCII(kTestMessage1Switch, kTestMessage);
205 cmd_line.AppendSwitchASCII(
206 kInheritedHandle1Switch,
207 base::UintToString(base::win::HandleToUint32(client.Get())));
208
209 base::Process child_process =
210 LaunchTestClient(&cmd_line, true /* sandboxed */, handles);
211
212 WriteMessageToPipe(server.Get(), kTestMessage);
213
214 int exit_code = 0;
215 child_process.WaitForExit(&exit_code);
216 EXPECT_EQ(0, exit_code);
217 }
218
219 // -----------------------------------------------------------------------------
220 // Tests follow: multi-handle inheritance.
221 // -----------------------------------------------------------------------------
222
223 MULTIPROCESS_TEST_MAIN(ReadMultiPipes) {
224 InitializeTestSandbox();
225
226 // Expects two messages and two pipe handles to be passed in, and expects to
227 // read each message from its respective pipe. Exits with 0 on success, 1 on
228 // failure.
229
230 base::win::ScopedHandle pipe1(
231 GetHandleFromCommandLine(kInheritedHandle1Switch));
232 std::string message1 = ReadMessageFromPipe(pipe1.Get());
233
234 if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
235 kTestMessage1Switch) != message1) {
236 return 1;
237 }
238
239 base::win::ScopedHandle pipe2(
240 GetHandleFromCommandLine(kInheritedHandle2Switch));
241 std::string message2 = ReadMessageFromPipe(pipe2.Get());
242
243 if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
244 kTestMessage2Switch) != message2) {
245 return 1;
246 }
247
248 return 0;
249 }
250
251 TEST_F(SandboxWinTest, InheritMultipleHandlesUnsandboxed) {
252 base::CommandLine cmd_line = MakeCmdLineWithExtension("ReadMultiPipes");
253
254 base::win::ScopedHandle server1, client1;
255 CreatePipe(&server1, &client1);
256
257 base::win::ScopedHandle server2, client2;
258 CreatePipe(&server2, &client2);
259
260 base::HandlesToInheritVector handles;
261 handles.push_back(client1.Get());
262 handles.push_back(client2.Get());
263
264 // Pass each pipe handle ID and a message for each on the command line.
265 const std::string kTestMessage1 = "Hello, world!";
266 const std::string kTestMessage2 = "Goodbye, world!";
267
268 cmd_line.AppendSwitchASCII(kTestMessage1Switch, kTestMessage1);
269 cmd_line.AppendSwitchASCII(
270 kInheritedHandle1Switch,
271 base::UintToString(base::win::HandleToUint32(client1.Get())));
272
273 cmd_line.AppendSwitchASCII(kTestMessage2Switch, kTestMessage2);
274 cmd_line.AppendSwitchASCII(
275 kInheritedHandle2Switch,
276 base::UintToString(base::win::HandleToUint32(client2.Get())));
277
278 base::Process child_process =
279 LaunchTestClient(&cmd_line, false /* sandboxed */, handles);
280
281 WriteMessageToPipe(server1.Get(), kTestMessage1);
282 WriteMessageToPipe(server2.Get(), kTestMessage2);
283
284 int exit_code = 0;
285 child_process.WaitForExit(&exit_code);
286 EXPECT_EQ(0, exit_code);
287 }
288
289 TEST_F(SandboxWinTest, InheritMultipleHandlesSandboxed) {
290 base::CommandLine cmd_line = MakeCmdLineWithExtension("ReadMultiPipes");
291
292 base::win::ScopedHandle server1, client1;
293 CreatePipe(&server1, &client1);
294
295 base::win::ScopedHandle server2, client2;
296 CreatePipe(&server2, &client2);
297
298 base::HandlesToInheritVector handles;
299 handles.push_back(client1.Get());
300 handles.push_back(client2.Get());
301
302 // Pass each pipe handle ID and a message for each on the command line.
303 const std::string kTestMessage1 = "Hello, world!";
304 const std::string kTestMessage2 = "Goodbye, world!";
305
306 cmd_line.AppendSwitchASCII(kTestMessage1Switch, kTestMessage1);
307 cmd_line.AppendSwitchASCII(
308 kInheritedHandle1Switch,
309 base::UintToString(base::win::HandleToUint32(client1.Get())));
310
311 cmd_line.AppendSwitchASCII(kTestMessage2Switch, kTestMessage2);
312 cmd_line.AppendSwitchASCII(
313 kInheritedHandle2Switch,
314 base::UintToString(base::win::HandleToUint32(client2.Get())));
315
316 base::Process child_process =
317 LaunchTestClient(&cmd_line, true /* sandboxed */, handles);
318
319 WriteMessageToPipe(server1.Get(), kTestMessage1);
320 WriteMessageToPipe(server2.Get(), kTestMessage2);
321
322 int exit_code = 0;
323 child_process.WaitForExit(&exit_code);
324 EXPECT_EQ(0, exit_code);
325 }
326
327 } // namespace
328 } // namespace
OLDNEW
« no previous file with comments | « no previous file | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698