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

Unified Diff: sandbox/linux/syscall_broker/broker_process_unittest.cc

Issue 721553002: sandbox: Extend BrokerPolicy to support file creation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor fix Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: sandbox/linux/syscall_broker/broker_process_unittest.cc
diff --git a/sandbox/linux/syscall_broker/broker_process_unittest.cc b/sandbox/linux/syscall_broker/broker_process_unittest.cc
index e7d5442c3b1ac656096ed6465258a2c1bd886f64..6a4adc160e513fb7b672687ff884abe693a79ac6 100644
--- a/sandbox/linux/syscall_broker/broker_process_unittest.cc
+++ b/sandbox/linux/syscall_broker/broker_process_unittest.cc
@@ -30,6 +30,7 @@
#include "testing/gtest/include/gtest/gtest.h"
namespace sandbox {
+using syscall_broker::BrokerPermission;
class BrokerProcessTestHelper {
public:
@@ -47,11 +48,10 @@ bool NoOpCallback() {
} // namespace
TEST(BrokerProcess, CreateAndDestroy) {
- std::vector<std::string> read_whitelist;
- read_whitelist.push_back("/proc/cpuinfo");
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_ONLY("/proc/cpuinfo"));
- scoped_ptr<BrokerProcess> open_broker(
- new BrokerProcess(EPERM, read_whitelist, std::vector<std::string>()));
+ scoped_ptr<BrokerProcess> open_broker(new BrokerProcess(EPERM, permissions));
ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
ASSERT_TRUE(TestUtils::CurrentProcessHasChildren());
@@ -61,8 +61,8 @@ TEST(BrokerProcess, CreateAndDestroy) {
}
TEST(BrokerProcess, TestOpenAccessNull) {
- const std::vector<std::string> empty;
- BrokerProcess open_broker(EPERM, empty, empty);
+ std::vector<syscall_broker::BrokerPermission> empty;
+ BrokerProcess open_broker(EPERM, empty);
ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
int fd = open_broker.Open(NULL, O_RDONLY);
@@ -81,17 +81,13 @@ void TestOpenFilePerms(bool fast_check_in_client, int denied_errno) {
const char kRW_WhiteListed[] = "/proc/DOESNOTEXIST3";
const char k_NotWhitelisted[] = "/proc/DOESNOTEXIST4";
- std::vector<std::string> read_whitelist;
- read_whitelist.push_back(kR_WhiteListed);
- read_whitelist.push_back(kR_WhiteListedButDenied);
- read_whitelist.push_back(kRW_WhiteListed);
-
- std::vector<std::string> write_whitelist;
- write_whitelist.push_back(kW_WhiteListed);
- write_whitelist.push_back(kRW_WhiteListed);
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_ONLY(kR_WhiteListed));
+ permissions.push_back(BROKER_PERM_READ_ONLY(kR_WhiteListedButDenied));
+ permissions.push_back(BROKER_PERM_WRITE_ONLY(kW_WhiteListed));
+ permissions.push_back(BROKER_PERM_READ_WRITE(kRW_WhiteListed));
- BrokerProcess open_broker(
- denied_errno, read_whitelist, write_whitelist, fast_check_in_client);
+ BrokerProcess open_broker(denied_errno, permissions, fast_check_in_client);
ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
int fd = -1;
@@ -236,13 +232,78 @@ TEST(BrokerProcess, OpenOpenFilePermsNoClientCheckNoEnt) {
// expected.
}
-void TestOpenCpuinfo(bool fast_check_in_client) {
+void TestBadPaths(bool fast_check_in_client) {
const char kFileCpuInfo[] = "/proc/cpuinfo";
- std::vector<std::string> read_whitelist;
- read_whitelist.push_back(kFileCpuInfo);
+ const char kNotAbsPath[] = "proc/cpuinfo";
+ const char kDotDotStart[] = "/../proc/cpuinfo";
+ const char kDotDotMiddle[] = "/proc/self/../cpuinfo";
+ const char kDotDotEnd[] = "/proc/..";
+ const char kTrailingSlash[] = "/proc/";
+
+ std::vector<syscall_broker::BrokerPermission> permissions;
- scoped_ptr<BrokerProcess> open_broker(new BrokerProcess(
- EPERM, read_whitelist, std::vector<std::string>(), fast_check_in_client));
+ permissions.push_back(BROKER_PERM_READ_ONLY_RECURSIVE("/proc/"));
+ scoped_ptr<BrokerProcess> open_broker(
+ new BrokerProcess(EPERM, permissions, fast_check_in_client));
+ ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
+ // Open cpuinfo via the broker.
+ int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY);
+ base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd);
+ ASSERT_GE(cpuinfo_fd, 0);
+
+ int fd = -1;
+ int can_access;
+
+ can_access = open_broker->Access(kNotAbsPath, R_OK);
+ ASSERT_EQ(can_access, -EPERM);
+ fd = open_broker->Open(kNotAbsPath, O_RDONLY);
+ ASSERT_EQ(fd, -EPERM);
+
+ can_access = open_broker->Access(kDotDotStart, R_OK);
+ ASSERT_EQ(can_access, -EPERM);
+ fd = open_broker->Open(kDotDotStart, O_RDONLY);
+ ASSERT_EQ(fd, -EPERM);
+
+ can_access = open_broker->Access(kDotDotMiddle, R_OK);
+ ASSERT_EQ(can_access, -EPERM);
+ fd = open_broker->Open(kDotDotMiddle, O_RDONLY);
+ ASSERT_EQ(fd, -EPERM);
+
+ can_access = open_broker->Access(kDotDotEnd, R_OK);
+ ASSERT_EQ(can_access, -EPERM);
+ fd = open_broker->Open(kDotDotEnd, O_RDONLY);
+ ASSERT_EQ(fd, -EPERM);
+
+ can_access = open_broker->Access(kTrailingSlash, R_OK);
+ ASSERT_EQ(can_access, -EPERM);
+ fd = open_broker->Open(kTrailingSlash, O_RDONLY);
+ ASSERT_EQ(fd, -EPERM);
+}
+
+TEST(BrokerProcess, BadPathsClientCheck) {
+ TestBadPaths(true /* fast_check_in_client */);
+ // Don't do anything here, so that ASSERT works in the subfunction as
+ // expected.
+}
+
+TEST(BrokerProcess, BadPathsNoClientCheck) {
+ TestBadPaths(false /* fast_check_in_client */);
+ // Don't do anything here, so that ASSERT works in the subfunction as
+ // expected.
+}
+
+void TestOpenCpuinfo(bool fast_check_in_client, bool recursive) {
+ const char kFileCpuInfo[] = "/proc/cpuinfo";
+ const char kDirProc[] = "/proc/";
+
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ if (recursive)
+ permissions.push_back(BROKER_PERM_READ_ONLY_RECURSIVE(kDirProc));
+ else
+ permissions.push_back(BROKER_PERM_READ_ONLY(kFileCpuInfo));
+
+ scoped_ptr<BrokerProcess> open_broker(
+ new BrokerProcess(EPERM, permissions, fast_check_in_client));
ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
int fd = -1;
@@ -286,16 +347,28 @@ void TestOpenCpuinfo(bool fast_check_in_client) {
ASSERT_FALSE(TestUtils::CurrentProcessHasChildren());
}
-// Run the same thing twice. The second time, we make sure that no security
-// check is performed on the client.
+// Run this test 4 times. With and without the check in client
+// and using a recursive path.
TEST(BrokerProcess, OpenCpuinfoWithClientCheck) {
- TestOpenCpuinfo(true /* fast_check_in_client */);
+ TestOpenCpuinfo(true /* fast_check_in_client */, false /* not recursive */);
// Don't do anything here, so that ASSERT works in the subfunction as
// expected.
}
TEST(BrokerProcess, OpenCpuinfoNoClientCheck) {
- TestOpenCpuinfo(false /* fast_check_in_client */);
+ TestOpenCpuinfo(false /* fast_check_in_client */, false /* not recursive */);
+ // Don't do anything here, so that ASSERT works in the subfunction as
+ // expected.
+}
+
+TEST(BrokerProcess, OpenCpuinfoWithClientCheckRecursive) {
+ TestOpenCpuinfo(true /* fast_check_in_client */, true /* recursive */);
+ // Don't do anything here, so that ASSERT works in the subfunction as
+ // expected.
+}
+
+TEST(BrokerProcess, OpenCpuinfoNoClientCheckRecursive) {
+ TestOpenCpuinfo(false /* fast_check_in_client */, true /* recursive */);
// Don't do anything here, so that ASSERT works in the subfunction as
// expected.
}
@@ -304,10 +377,10 @@ TEST(BrokerProcess, OpenFileRW) {
ScopedTemporaryFile tempfile;
const char* tempfile_name = tempfile.full_file_name();
- std::vector<std::string> whitelist;
- whitelist.push_back(tempfile_name);
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_WRITE(tempfile_name));
- BrokerProcess open_broker(EPERM, whitelist, whitelist);
+ BrokerProcess open_broker(EPERM, permissions);
ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
// Check we can access that file with read or write.
@@ -337,13 +410,11 @@ TEST(BrokerProcess, OpenFileRW) {
// SANDBOX_TEST because the process could die with a SIGPIPE
// and we want this to happen in a subprocess.
SANDBOX_TEST(BrokerProcess, BrokerDied) {
- std::vector<std::string> read_whitelist;
- read_whitelist.push_back("/proc/cpuinfo");
+ const char kCpuInfo[] = "/proc/cpuinfo";
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_ONLY(kCpuInfo));
- BrokerProcess open_broker(EPERM,
- read_whitelist,
- std::vector<std::string>(),
- true /* fast_check_in_client */,
+ BrokerProcess open_broker(EPERM, permissions, true /* fast_check_in_client */,
true /* quiet_failures_for_tests */);
SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback)));
const pid_t broker_pid = open_broker.broker_pid();
@@ -359,16 +430,16 @@ SANDBOX_TEST(BrokerProcess, BrokerDied) {
SANDBOX_ASSERT(SIGKILL == process_info.si_status);
// Check that doing Open with a dead broker won't SIGPIPE us.
- SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM);
- SANDBOX_ASSERT(open_broker.Access("/proc/cpuinfo", O_RDONLY) == -ENOMEM);
+ SANDBOX_ASSERT(open_broker.Open(kCpuInfo, O_RDONLY) == -ENOMEM);
+ SANDBOX_ASSERT(open_broker.Access(kCpuInfo, O_RDONLY) == -ENOMEM);
}
void TestOpenComplexFlags(bool fast_check_in_client) {
const char kCpuInfo[] = "/proc/cpuinfo";
- std::vector<std::string> whitelist;
- whitelist.push_back(kCpuInfo);
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_ONLY(kCpuInfo));
- BrokerProcess open_broker(EPERM, whitelist, whitelist, fast_check_in_client);
+ BrokerProcess open_broker(EPERM, permissions, fast_check_in_client);
ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
// Test that we do the right thing for O_CLOEXEC and O_NONBLOCK.
int fd = -1;
@@ -447,10 +518,10 @@ SANDBOX_TEST_ALLOW_NOISE(BrokerProcess, RecvMsgDescriptorLeak) {
SANDBOX_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim));
static const char kCpuInfo[] = "/proc/cpuinfo";
- std::vector<std::string> read_whitelist;
- read_whitelist.push_back(kCpuInfo);
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_ONLY(kCpuInfo));
- BrokerProcess open_broker(EPERM, read_whitelist, std::vector<std::string>());
+ BrokerProcess open_broker(EPERM, permissions);
SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback)));
const int ipc_fd = BrokerProcessTestHelper::get_ipc_socketpair(&open_broker);
@@ -472,4 +543,59 @@ SANDBOX_TEST_ALLOW_NOISE(BrokerProcess, RecvMsgDescriptorLeak) {
SANDBOX_ASSERT(0 == IGNORE_EINTR(close(fd)));
}
+void GetTempFileName(char* name, size_t len) {
+#if defined(OS_ANDROID)
+ static const char file_template[] = "/data/local/tmp/BrokerTempFileXXXXXX";
+#else
+ static const char file_template[] = "/tmp/BrokerTempFileXXXXXX";
+#endif // defined(OS_ANDROID)
+
+ ASSERT_GT(len, sizeof(file_template));
+
+ strncpy(name, file_template, len);
+ int fd = mkstemp(name);
+ ASSERT_GT(fd, 0);
+ ASSERT_EQ(0, unlink(name));
+ ASSERT_EQ(0, IGNORE_EINTR(close(fd)));
+}
+
+TEST(BrokerProcess, CreateFile) {
+ char tempfile_name[256] = "";
+
+ GetTempFileName(tempfile_name, sizeof(tempfile_name));
+
+ std::vector<syscall_broker::BrokerPermission> permissions;
+ permissions.push_back(BROKER_PERM_READ_WRITE_CREATE(tempfile_name));
+
+ BrokerProcess open_broker(EPERM, permissions);
+ ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
+
+ int fd = -1;
+
+ // Try without O_EXCL
+ fd = open_broker.Open(tempfile_name, O_RDWR | O_CREAT);
+ ASSERT_EQ(fd, -1);
+
+ // Create a file
+ fd = open_broker.Open(tempfile_name, O_RDWR | O_CREAT | O_EXCL);
+ ASSERT_GE(fd, 0);
+
+ // Write to the descriptor opened by the broker.
+ char test_text[] = "TESTTESTTEST";
+ ssize_t len = write(fd, test_text, sizeof(test_text));
+ ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text)));
+
+ ASSERT_EQ(close(fd), 0);
+
+ int fd_check = open(tempfile_name, O_RDONLY);
+ ASSERT_GE(fd_check, 0);
+ char buf[1024];
+ len = read(fd_check, buf, sizeof(buf));
+
+ ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text)));
+ ASSERT_EQ(memcmp(test_text, buf, sizeof(test_text)), 0);
+
+ ASSERT_EQ(close(fd_check), 0);
+}
+
} // namespace sandbox

Powered by Google App Engine
This is Rietveld 408576698