| Index: sandbox/linux/services/broker_process_unittest.cc
|
| diff --git a/sandbox/linux/services/broker_process_unittest.cc b/sandbox/linux/services/broker_process_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f56b27df9d50fa24c37050a91d15be12d71402bf
|
| --- /dev/null
|
| +++ b/sandbox/linux/services/broker_process_unittest.cc
|
| @@ -0,0 +1,125 @@
|
| +#include "sandbox/linux/services/broker_process.h"
|
| +
|
| +#include <errno.h>
|
| +#include <fcntl.h>
|
| +#include <sys/stat.h>
|
| +#include <sys/types.h>
|
| +#include <sys/wait.h>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "sandbox/linux/tests/unit_tests.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace sandbox {
|
| +
|
| +TEST(BrokerProcess, CreateAndDestroy) {
|
| + std::vector<std::string> file_whitelist;
|
| + file_whitelist.push_back("/proc/cpuinfo");
|
| +
|
| + BrokerProcess* open_broker = new BrokerProcess(file_whitelist);
|
| + EXPECT_TRUE(open_broker->Init(NULL));
|
| + pid_t broker_pid = open_broker->broker_pid();
|
| + delete(open_broker);
|
| +
|
| + // Now we check that the broker has exited properly.
|
| + int status = 0;
|
| + EXPECT_EQ(waitpid(broker_pid, &status, 0), broker_pid);
|
| + EXPECT_TRUE(WIFEXITED(status));
|
| + EXPECT_EQ(WEXITSTATUS(status), 0);
|
| +}
|
| +
|
| +void TestOpenFile(bool fast_check_in_client) {
|
| + std::vector<std::string> file_whitelist;
|
| + const char kFileCpuInfo[] = "/proc/cpuinfo";
|
| + const char kDoesNotExistWhitelisted[] = "/proc/DOESNOTEXIST";
|
| + const char kDoesNotExist2[] = "/proc/DOESNOTEXIST2";
|
| + file_whitelist.push_back(kFileCpuInfo);
|
| + file_whitelist.push_back(kDoesNotExistWhitelisted);
|
| +
|
| + BrokerProcess* open_broker = new BrokerProcess(file_whitelist,
|
| + fast_check_in_client);
|
| + EXPECT_TRUE(open_broker->Init(NULL));
|
| + pid_t broker_pid = open_broker->broker_pid();
|
| +
|
| + int fd = -1;
|
| + // This file is not whitelisted.
|
| + fd = open_broker->Open(kDoesNotExist2, O_RDONLY);
|
| + EXPECT_EQ(fd, -EPERM);
|
| + // This file is whitelisted.
|
| + fd = open_broker->Open(kDoesNotExistWhitelisted, O_RDONLY);
|
| + EXPECT_EQ(fd, -ENOENT);
|
| + fd = open_broker->Open(kFileCpuInfo, O_RDWR);
|
| + EXPECT_EQ(fd, -EPERM);
|
| +
|
| + // Open cpuinfo via the broker.
|
| + int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY);
|
| + ASSERT_GE(cpuinfo_fd, 0);
|
| + char buf[3];
|
| + memset(buf, 0, sizeof(buf));
|
| + int read_len1 = read(cpuinfo_fd, buf, sizeof(buf));
|
| + EXPECT_GT(read_len1, 0);
|
| +
|
| + // Open cpuinfo directly.
|
| + int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY);
|
| + ASSERT_GE(cpuinfo_fd2, 0);
|
| + char buf2[3];
|
| + memset(buf2, 1, sizeof(buf2));
|
| + int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2));
|
| + EXPECT_GT(read_len1, 0);
|
| +
|
| + // The following is not guaranteed true, but will be in practice.
|
| + EXPECT_EQ(read_len1, read_len2);
|
| + // Compare the cpuinfo as returned by the broker with the one we opened
|
| + // ourselves.
|
| + EXPECT_EQ(memcmp(buf, buf2, read_len1), 0);
|
| +
|
| + if (fd >= 0)
|
| + close(fd);
|
| + if (cpuinfo_fd >= 0)
|
| + close(cpuinfo_fd);
|
| + if (cpuinfo_fd2 >= 0)
|
| + close(cpuinfo_fd);
|
| +
|
| + delete(open_broker);
|
| +
|
| + // Now we check that the broker has exited properly.
|
| + int status = 0;
|
| + EXPECT_EQ(waitpid(broker_pid, &status, 0), broker_pid);
|
| + EXPECT_TRUE(WIFEXITED(status));
|
| + EXPECT_EQ(WEXITSTATUS(status), 0);
|
| +}
|
| +
|
| +// Run the same thing twice. The second time, we make sure that no security
|
| +// check is performed on the client.
|
| +TEST(BrokerProcess, OpenFileWithClientCheck) {
|
| + TestOpenFile(true /* fast_check_in_client */);
|
| +}
|
| +
|
| +TEST(BrokerProcess, OpenFileNoClientCheck) {
|
| + TestOpenFile(false /* fast_check_in_client */);
|
| +}
|
| +
|
| +// Sandbox test because we could get a SIGPIPE.
|
| +SANDBOX_TEST(BrokerProcess, BrokerDied) {
|
| + std::vector<std::string> file_whitelist;
|
| + file_whitelist.push_back("/proc/cpuinfo");
|
| +
|
| + BrokerProcess open_broker(file_whitelist,
|
| + true /* fast_check_in_client */,
|
| + true /* quiet_failures_for_tests */);
|
| + SANDBOX_ASSERT(open_broker.Init(NULL));
|
| + pid_t broker_pid = open_broker.broker_pid();
|
| + SANDBOX_ASSERT(kill(broker_pid, SIGKILL) == 0);
|
| +
|
| + // Now we check that the broker has exited properly.
|
| + int status = 0;
|
| + SANDBOX_ASSERT(waitpid(broker_pid, &status, 0) == broker_pid);
|
| + SANDBOX_ASSERT(WIFSIGNALED(status));
|
| + SANDBOX_ASSERT(WTERMSIG(status) == SIGKILL);
|
| + // Hopefully doing Open with a dead broker won't SIGPIPE us.
|
| + SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM);
|
| +}
|
| +
|
| +} // namespace sandbox
|
|
|