| 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 |