Bug 1289718 - Fix Link tests and path passing. draft
authorGian-Carlo Pascutto <gcp@mozilla.com>
Wed, 24 Aug 2016 20:03:15 +0200
changeset 409935 5df5fcf01590a9138c3ca72371e5e1d3498cf85b
parent 409934 8c08d3a0ba62a07cd0912af1dc725d6454ef05dd
child 409936 c6db11730ee842db0167eabea4d2c132100ed3de
push id28613
push usergpascutto@mozilla.com
push dateMon, 05 Sep 2016 18:00:21 +0000
bugs1289718
milestone51.0a1
Bug 1289718 - Fix Link tests and path passing. MozReview-Commit-ID: 6IzqdrUP7lD
security/sandbox/linux/SandboxBrokerClient.cpp
security/sandbox/linux/gtest/TestBroker.cpp
--- a/security/sandbox/linux/SandboxBrokerClient.cpp
+++ b/security/sandbox/linux/SandboxBrokerClient.cpp
@@ -66,20 +66,20 @@ SandboxBrokerClient::DoCall(const Reques
 
   struct iovec ios[3];
   int respFds[3];
 
   // Set up iovecs for request + path.
   ios[0].iov_base = const_cast<Request*>(aReq);
   ios[0].iov_len = sizeof(*aReq);
   ios[1].iov_base = const_cast<char*>(path);
-  ios[1].iov_len = strlen(path);
+  ios[1].iov_len = strlen(path) + 1;
   if (aPath2 != nullptr) {
     ios[2].iov_base = const_cast<char*>(aPath2);
-    ios[2].iov_len = strlen(aPath2);
+    ios[2].iov_len = strlen(aPath2) + 1;
   } else {
     ios[2].iov_base = 0;
     ios[2].iov_len = 0;
   }
   if (ios[1].iov_len > kMaxPathLen) {
     return -ENAMETOOLONG;
   }
   if (ios[2].iov_len > kMaxPathLen) {
--- a/security/sandbox/linux/gtest/TestBroker.cpp
+++ b/security/sandbox/linux/gtest/TestBroker.cpp
@@ -58,16 +58,19 @@ protected:
     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);
   }
+  int Link(const char* aPath, const char* bPath) {
+    return mClient->Link(aPath, bPath);
+  }
 
   virtual void SetUp() {
     ipc::FileDescriptor fd;
 
     mServer = SandboxBroker::Create(GetPolicy(), getpid(), fd);
     ASSERT_NE(mServer, nullptr);
     ASSERT_TRUE(fd.IsValid());
     auto rawFD = fd.ClonePlatformHandle();
@@ -103,17 +106,19 @@ 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");
+  policy->AddPath(MAY_READ | MAY_WRITE, "/tmp", AddAlways);
+  policy->AddPath(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp/blublu", AddAlways);
+  policy->AddPath(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp/blublublu", AddAlways);
 
   return Move(policy);
 }
 
 TEST_F(SandboxBrokerTest, OpenForRead)
 {
   int fd;
 
@@ -231,16 +236,31 @@ TEST_F(SandboxBrokerTest, Chmod)
   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, Link)
+{
+  unlink("/tmp/blublu");
+  unlink("/tmp/blublublu");
+  int fd = Open("/tmp/blublu", O_WRONLY | O_CREAT);
+  ASSERT_GE(fd, 0) << "Opening /tmp/blublu for writing failed.";
+  close(fd);
+  ASSERT_EQ(0, Link("/tmp/blublu", "/tmp/blublublu"));
+  EXPECT_EQ(0, Access("/tmp/blublublu", F_OK));
+  // Not whitelisted target path
+  EXPECT_EQ(-EACCES, Link("/tmp/blublu", "/tmp/nope"));
+  EXPECT_EQ(0, unlink("/tmp/blublublu"));
+  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) {