Bug 1289718 - Add test for Chmod brokering. draft
authorGian-Carlo Pascutto <gcp@mozilla.com>
Wed, 24 Aug 2016 18:01:06 +0200
changeset 409934 8c08d3a0ba62a07cd0912af1dc725d6454ef05dd
parent 409933 2f9e7af79ac69608b33d9500c122e051e784f60a
child 409935 5df5fcf01590a9138c3ca72371e5e1d3498cf85b
push id28613
push usergpascutto@mozilla.com
push dateMon, 05 Sep 2016 18:00:21 +0000
bugs1289718
milestone51.0a1
Bug 1289718 - Add test for Chmod brokering. MozReview-Commit-ID: HOWR0HEHmMg
security/sandbox/linux/gtest/TestBroker.cpp
--- a/security/sandbox/linux/gtest/TestBroker.cpp
+++ b/security/sandbox/linux/gtest/TestBroker.cpp
@@ -26,17 +26,17 @@
 #include "mozilla/UniquePtr.h"
 #include "mozilla/ipc/FileDescriptor.h"
 
 namespace mozilla {
 
 static const int MAY_ACCESS = SandboxBroker::MAY_ACCESS;
 static const int MAY_READ = SandboxBroker::MAY_READ;
 static const int MAY_WRITE = SandboxBroker::MAY_WRITE;
-//static const int MAY_CREATE = SandboxBroker::MAY_CREATE;
+static const int MAY_CREATE = SandboxBroker::MAY_CREATE;
 static const auto AddAlways = SandboxBroker::Policy::AddAlways;
 
 class SandboxBrokerTest : public ::testing::Test
 {
   UniquePtr<SandboxBroker> mServer;
   UniquePtr<SandboxBrokerClient> mClient;
 
   UniquePtr<const SandboxBroker::Policy> GetPolicy() const;
@@ -55,16 +55,19 @@ protected:
     return mClient->Access(aPath, aMode);
   }
   int Stat(const char* aPath, struct stat* aStat) {
     return mClient->Stat(aPath, aStat);
   }
   int LStat(const char* aPath, struct stat* aStat) {
     return mClient->LStat(aPath, aStat);
   }
+  int Chmod(const char* aPath, int aMode) {
+    return mClient->Chmod(aPath, aMode);
+  }
 
   virtual void SetUp() {
     ipc::FileDescriptor fd;
 
     mServer = SandboxBroker::Create(GetPolicy(), getpid(), fd);
     ASSERT_NE(mServer, nullptr);
     ASSERT_TRUE(fd.IsValid());
     auto rawFD = fd.ClonePlatformHandle();
@@ -100,16 +103,17 @@ UniquePtr<const SandboxBroker::Policy>
 SandboxBrokerTest::GetPolicy() const
 {
   UniquePtr<SandboxBroker::Policy> policy(new SandboxBroker::Policy());
 
   policy->AddPath(MAY_READ | MAY_WRITE, "/dev/null", AddAlways);
   policy->AddPath(MAY_READ, "/dev/zero", AddAlways);
   policy->AddPath(MAY_READ, "/var/empty/qwertyuiop", AddAlways);
   policy->AddPath(MAY_ACCESS, "/proc/self", AddAlways); // Warning: Linux-specific.
+  policy->AddDir(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp");
 
   return Move(policy);
 }
 
 TEST_F(SandboxBrokerTest, OpenForRead)
 {
   int fd;
 
@@ -205,16 +209,38 @@ TEST_F(SandboxBrokerTest, LStat)
 
   EXPECT_EQ(-ENOENT, LStat("/var/empty/qwertyuiop", &brokeredStat));
   EXPECT_EQ(-EACCES, LStat("/dev", &brokeredStat));
 
   EXPECT_EQ(0, LStat("/proc/self", &brokeredStat));
   EXPECT_TRUE(S_ISLNK(brokeredStat.st_mode));
 }
 
+TEST_F(SandboxBrokerTest, Chmod)
+{
+  unlink("/tmp/blublu");
+  int fd = Open("/tmp/blublu", O_WRONLY | O_CREAT);
+  ASSERT_GE(fd, 0) << "Opening /tmp/blublu for writing failed.";
+  close(fd);
+  // Set read only. SandboxBroker enforces 0600 mode flags.
+  ASSERT_EQ(0, Chmod("/tmp/blublu", S_IRUSR));
+  // SandboxBroker doesn't use real access(), it just checks against
+  // the policy. So it can't see the change in permisions here.
+  // This won't work:
+  // EXPECT_EQ(-EACCES, Access("/tmp/blublu", W_OK));
+  struct stat realStat;
+  EXPECT_EQ(0, stat("/tmp/blublu", &realStat));
+  EXPECT_EQ((mode_t)S_IRUSR, realStat.st_mode & 0777);
+
+  ASSERT_EQ(0, Chmod("/tmp/blublu", S_IRUSR | S_IWUSR));
+  EXPECT_EQ(0, stat("/tmp/blublu", &realStat));
+  EXPECT_EQ((mode_t)(S_IRUSR | S_IWUSR), realStat.st_mode & 0777);
+  EXPECT_EQ(0, unlink("/tmp/blublu"));
+}
+
 TEST_F(SandboxBrokerTest, MultiThreadOpen) {
   RunOnManyThreads<SandboxBrokerTest,
                    &SandboxBrokerTest::MultiThreadOpenWorker>();
 }
 void SandboxBrokerTest::MultiThreadOpenWorker() {
   static const int kNumLoops = 10000;
 
   for (int i = 1; i <= kNumLoops; ++i) {