OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/linux/services/broker_process.h" | 5 #include "sandbox/linux/syscall_broker/broker_process.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/resource.h> | 9 #include <sys/resource.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
11 #include <sys/types.h> | 11 #include <sys/types.h> |
12 #include <sys/wait.h> | 12 #include <sys/wait.h> |
13 #include <unistd.h> | 13 #include <unistd.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
(...skipping 17 matching lines...) Expand all Loading... |
33 | 33 |
34 class BrokerProcessTestHelper { | 34 class BrokerProcessTestHelper { |
35 public: | 35 public: |
36 static int get_ipc_socketpair(const BrokerProcess* broker) { | 36 static int get_ipc_socketpair(const BrokerProcess* broker) { |
37 return broker->ipc_socketpair_; | 37 return broker->ipc_socketpair_; |
38 } | 38 } |
39 }; | 39 }; |
40 | 40 |
41 namespace { | 41 namespace { |
42 | 42 |
43 bool NoOpCallback() { return true; } | 43 bool NoOpCallback() { |
| 44 return true; |
| 45 } |
44 | 46 |
45 } // namespace | 47 } // namespace |
46 | 48 |
47 TEST(BrokerProcess, CreateAndDestroy) { | 49 TEST(BrokerProcess, CreateAndDestroy) { |
48 std::vector<std::string> read_whitelist; | 50 std::vector<std::string> read_whitelist; |
49 read_whitelist.push_back("/proc/cpuinfo"); | 51 read_whitelist.push_back("/proc/cpuinfo"); |
50 | 52 |
51 scoped_ptr<BrokerProcess> open_broker( | 53 scoped_ptr<BrokerProcess> open_broker( |
52 new BrokerProcess(EPERM, read_whitelist, std::vector<std::string>())); | 54 new BrokerProcess(EPERM, read_whitelist, std::vector<std::string>())); |
53 ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); | 55 ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); |
(...skipping 27 matching lines...) Expand all Loading... |
81 | 83 |
82 std::vector<std::string> read_whitelist; | 84 std::vector<std::string> read_whitelist; |
83 read_whitelist.push_back(kR_WhiteListed); | 85 read_whitelist.push_back(kR_WhiteListed); |
84 read_whitelist.push_back(kR_WhiteListedButDenied); | 86 read_whitelist.push_back(kR_WhiteListedButDenied); |
85 read_whitelist.push_back(kRW_WhiteListed); | 87 read_whitelist.push_back(kRW_WhiteListed); |
86 | 88 |
87 std::vector<std::string> write_whitelist; | 89 std::vector<std::string> write_whitelist; |
88 write_whitelist.push_back(kW_WhiteListed); | 90 write_whitelist.push_back(kW_WhiteListed); |
89 write_whitelist.push_back(kRW_WhiteListed); | 91 write_whitelist.push_back(kRW_WhiteListed); |
90 | 92 |
91 BrokerProcess open_broker(denied_errno, | 93 BrokerProcess open_broker( |
92 read_whitelist, | 94 denied_errno, read_whitelist, write_whitelist, fast_check_in_client); |
93 write_whitelist, | |
94 fast_check_in_client); | |
95 ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); | 95 ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); |
96 | 96 |
97 int fd = -1; | 97 int fd = -1; |
98 fd = open_broker.Open(kR_WhiteListed, O_RDONLY); | 98 fd = open_broker.Open(kR_WhiteListed, O_RDONLY); |
99 ASSERT_EQ(fd, -ENOENT); | 99 ASSERT_EQ(fd, -ENOENT); |
100 fd = open_broker.Open(kR_WhiteListed, O_WRONLY); | 100 fd = open_broker.Open(kR_WhiteListed, O_WRONLY); |
101 ASSERT_EQ(fd, -denied_errno); | 101 ASSERT_EQ(fd, -denied_errno); |
102 fd = open_broker.Open(kR_WhiteListed, O_RDWR); | 102 fd = open_broker.Open(kR_WhiteListed, O_RDWR); |
103 ASSERT_EQ(fd, -denied_errno); | 103 ASSERT_EQ(fd, -denied_errno); |
104 int ret = -1; | 104 int ret = -1; |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 // Check that doing Open with a dead broker won't SIGPIPE us. | 361 // Check that doing Open with a dead broker won't SIGPIPE us. |
362 SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM); | 362 SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM); |
363 SANDBOX_ASSERT(open_broker.Access("/proc/cpuinfo", O_RDONLY) == -ENOMEM); | 363 SANDBOX_ASSERT(open_broker.Access("/proc/cpuinfo", O_RDONLY) == -ENOMEM); |
364 } | 364 } |
365 | 365 |
366 void TestOpenComplexFlags(bool fast_check_in_client) { | 366 void TestOpenComplexFlags(bool fast_check_in_client) { |
367 const char kCpuInfo[] = "/proc/cpuinfo"; | 367 const char kCpuInfo[] = "/proc/cpuinfo"; |
368 std::vector<std::string> whitelist; | 368 std::vector<std::string> whitelist; |
369 whitelist.push_back(kCpuInfo); | 369 whitelist.push_back(kCpuInfo); |
370 | 370 |
371 BrokerProcess open_broker(EPERM, | 371 BrokerProcess open_broker(EPERM, whitelist, whitelist, fast_check_in_client); |
372 whitelist, | |
373 whitelist, | |
374 fast_check_in_client); | |
375 ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); | 372 ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); |
376 // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK. | 373 // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK. |
377 int fd = -1; | 374 int fd = -1; |
378 int ret = 0; | 375 int ret = 0; |
379 fd = open_broker.Open(kCpuInfo, O_RDONLY); | 376 fd = open_broker.Open(kCpuInfo, O_RDONLY); |
380 ASSERT_GE(fd, 0); | 377 ASSERT_GE(fd, 0); |
381 ret = fcntl(fd, F_GETFL); | 378 ret = fcntl(fd, F_GETFL); |
382 ASSERT_NE(-1, ret); | 379 ASSERT_NE(-1, ret); |
383 // The descriptor shouldn't have the O_CLOEXEC attribute, nor O_NONBLOCK. | 380 // The descriptor shouldn't have the O_CLOEXEC attribute, nor O_NONBLOCK. |
384 ASSERT_EQ(0, ret & (O_CLOEXEC | O_NONBLOCK)); | 381 ASSERT_EQ(0, ret & (O_CLOEXEC | O_NONBLOCK)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 base::ScopedFD message_fd(available_fds[0]); | 427 base::ScopedFD message_fd(available_fds[0]); |
431 for (size_t i = 1; i < arraysize(available_fds); i++) { | 428 for (size_t i = 1; i < arraysize(available_fds); i++) { |
432 SANDBOX_ASSERT(0 == IGNORE_EINTR(close(available_fds[i]))); | 429 SANDBOX_ASSERT(0 == IGNORE_EINTR(close(available_fds[i]))); |
433 } | 430 } |
434 | 431 |
435 // Lower our file descriptor limit to just allow three more file descriptors | 432 // Lower our file descriptor limit to just allow three more file descriptors |
436 // to be allocated. (N.B., RLIMIT_NOFILE doesn't limit the number of file | 433 // to be allocated. (N.B., RLIMIT_NOFILE doesn't limit the number of file |
437 // descriptors a process can have: it only limits the highest value that can | 434 // descriptors a process can have: it only limits the highest value that can |
438 // be assigned to newly-created descriptors allocated by the process.) | 435 // be assigned to newly-created descriptors allocated by the process.) |
439 const rlim_t fd_limit = | 436 const rlim_t fd_limit = |
440 1 + *std::max_element(available_fds, | 437 1 + |
441 available_fds + arraysize(available_fds)); | 438 *std::max_element(available_fds, |
| 439 available_fds + arraysize(available_fds)); |
442 | 440 |
443 // Valgrind doesn't allow changing the hard descriptor limit, so we only | 441 // Valgrind doesn't allow changing the hard descriptor limit, so we only |
444 // change the soft descriptor limit here. | 442 // change the soft descriptor limit here. |
445 struct rlimit rlim; | 443 struct rlimit rlim; |
446 SANDBOX_ASSERT(0 == getrlimit(RLIMIT_NOFILE, &rlim)); | 444 SANDBOX_ASSERT(0 == getrlimit(RLIMIT_NOFILE, &rlim)); |
447 SANDBOX_ASSERT(fd_limit <= rlim.rlim_cur); | 445 SANDBOX_ASSERT(fd_limit <= rlim.rlim_cur); |
448 rlim.rlim_cur = fd_limit; | 446 rlim.rlim_cur = fd_limit; |
449 SANDBOX_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim)); | 447 SANDBOX_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim)); |
450 | 448 |
451 static const char kCpuInfo[] = "/proc/cpuinfo"; | 449 static const char kCpuInfo[] = "/proc/cpuinfo"; |
(...skipping 16 matching lines...) Expand all Loading... |
468 SANDBOX_ASSERT( | 466 SANDBOX_ASSERT( |
469 UnixDomainSocket::SendMsg(ipc_fd, kBogus, sizeof(kBogus), fds)); | 467 UnixDomainSocket::SendMsg(ipc_fd, kBogus, sizeof(kBogus), fds)); |
470 } | 468 } |
471 | 469 |
472 const int fd = open_broker.Open(kCpuInfo, O_RDONLY); | 470 const int fd = open_broker.Open(kCpuInfo, O_RDONLY); |
473 SANDBOX_ASSERT(fd >= 0); | 471 SANDBOX_ASSERT(fd >= 0); |
474 SANDBOX_ASSERT(0 == IGNORE_EINTR(close(fd))); | 472 SANDBOX_ASSERT(0 == IGNORE_EINTR(close(fd))); |
475 } | 473 } |
476 | 474 |
477 } // namespace sandbox | 475 } // namespace sandbox |
OLD | NEW |