// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/linux/services/credentials.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "sandbox/linux/tests/unit_tests.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace sandbox {

namespace {

bool DirectoryExists(const char* path) {
  struct stat dir;
  errno = 0;
  int ret = stat(path, &dir);
  return -1 != ret || ENOENT != errno;
}

bool WorkingDirectoryIsRoot() {
  char current_dir[PATH_MAX];
  char* cwd = getcwd(current_dir, sizeof(current_dir));
  PCHECK(cwd);
  if (strcmp("/", cwd)) return false;

  // The current directory is the root. Add a few paranoid checks.
  struct stat current;
  CHECK_EQ(0, stat(".", &current));
  struct stat parrent;
  CHECK_EQ(0, stat("..", &parrent));
  CHECK_EQ(current.st_dev, parrent.st_dev);
  CHECK_EQ(current.st_ino, parrent.st_ino);
  CHECK_EQ(current.st_mode, parrent.st_mode);
  CHECK_EQ(current.st_uid, parrent.st_uid);
  CHECK_EQ(current.st_gid, parrent.st_gid);
  return true;
}

// Give dynamic tools a simple thing to test.
TEST(Credentials, CreateAndDestroy) {
  {
    Credentials cred1;
    (void) cred1;
  }
  scoped_ptr<Credentials> cred2(new Credentials);
}

TEST(Credentials, CountOpenFds) {
  base::ScopedFD proc_fd(open("/proc", O_RDONLY | O_DIRECTORY));
  ASSERT_TRUE(proc_fd.is_valid());
  Credentials creds;
  int fd_count = creds.CountOpenFds(proc_fd.get());
  int fd = open("/dev/null", O_RDONLY);
  ASSERT_LE(0, fd);
  EXPECT_EQ(fd_count + 1, creds.CountOpenFds(proc_fd.get()));
  ASSERT_EQ(0, IGNORE_EINTR(close(fd)));
  EXPECT_EQ(fd_count, creds.CountOpenFds(proc_fd.get()));
}

TEST(Credentials, HasOpenDirectory) {
  Credentials creds;
  // No open directory should exist at startup.
  EXPECT_FALSE(creds.HasOpenDirectory(-1));
  {
    // Have a "/dev" file descriptor around.
    int dev_fd = open("/dev", O_RDONLY | O_DIRECTORY);
    base::ScopedFD dev_fd_closer(dev_fd);
    EXPECT_TRUE(creds.HasOpenDirectory(-1));
  }
  EXPECT_FALSE(creds.HasOpenDirectory(-1));
}

TEST(Credentials, HasOpenDirectoryWithFD) {
  Credentials creds;

  int proc_fd = open("/proc", O_RDONLY | O_DIRECTORY);
  base::ScopedFD proc_fd_closer(proc_fd);
  ASSERT_LE(0, proc_fd);

  // Don't pass |proc_fd|, an open directory (proc_fd) should
  // be detected.
  EXPECT_TRUE(creds.HasOpenDirectory(-1));
  // Pass |proc_fd| and no open directory should be detected.
  EXPECT_FALSE(creds.HasOpenDirectory(proc_fd));

  {
    // Have a "/dev" file descriptor around.
    int dev_fd = open("/dev", O_RDONLY | O_DIRECTORY);
    base::ScopedFD dev_fd_closer(dev_fd);
    EXPECT_TRUE(creds.HasOpenDirectory(proc_fd));
  }

  // The "/dev" file descriptor should now be closed, |proc_fd| is the only
  // directory file descriptor open.
  EXPECT_FALSE(creds.HasOpenDirectory(proc_fd));
}

SANDBOX_TEST(Credentials, DropAllCaps) {
  Credentials creds;
  CHECK(creds.DropAllCapabilities());
  CHECK(!creds.HasAnyCapability());
}

SANDBOX_TEST(Credentials, GetCurrentCapString) {
  Credentials creds;
  CHECK(creds.DropAllCapabilities());
  const char kNoCapabilityText[] = "=";
  CHECK(*creds.GetCurrentCapString() == kNoCapabilityText);
}

SANDBOX_TEST(Credentials, MoveToNewUserNS) {
  Credentials creds;
  creds.DropAllCapabilities();
  bool moved_to_new_ns = creds.MoveToNewUserNS();
  fprintf(stdout,
          "Unprivileged CLONE_NEWUSER supported: %s\n",
          moved_to_new_ns ? "true." : "false.");
  fflush(stdout);
  if (!moved_to_new_ns) {
    fprintf(stdout, "This kernel does not support unprivileged namespaces. "
            "USERNS tests will succeed without running.\n");
    fflush(stdout);
    return;
  }
  CHECK(creds.HasAnyCapability());
  creds.DropAllCapabilities();
  CHECK(!creds.HasAnyCapability());
}

SANDBOX_TEST(Credentials, SupportsUserNS) {
  Credentials creds;
  creds.DropAllCapabilities();
  bool user_ns_supported = Credentials::SupportsNewUserNS();
  bool moved_to_new_ns = creds.MoveToNewUserNS();
  CHECK_EQ(user_ns_supported, moved_to_new_ns);
}

SANDBOX_TEST(Credentials, UidIsPreserved) {
  Credentials creds;
  creds.DropAllCapabilities();
  uid_t old_ruid, old_euid, old_suid;
  gid_t old_rgid, old_egid, old_sgid;
  PCHECK(0 == getresuid(&old_ruid, &old_euid, &old_suid));
  PCHECK(0 == getresgid(&old_rgid, &old_egid, &old_sgid));
  // Probably missing kernel support.
  if (!creds.MoveToNewUserNS()) return;
  uid_t new_ruid, new_euid, new_suid;
  PCHECK(0 == getresuid(&new_ruid, &new_euid, &new_suid));
  CHECK(old_ruid == new_ruid);
  CHECK(old_euid == new_euid);
  CHECK(old_suid == new_suid);

  gid_t new_rgid, new_egid, new_sgid;
  PCHECK(0 == getresgid(&new_rgid, &new_egid, &new_sgid));
  CHECK(old_rgid == new_rgid);
  CHECK(old_egid == new_egid);
  CHECK(old_sgid == new_sgid);
}

bool NewUserNSCycle(Credentials* creds) {
  DCHECK(creds);
  if (!creds->MoveToNewUserNS() ||
      !creds->HasAnyCapability() ||
      !creds->DropAllCapabilities() ||
      creds->HasAnyCapability()) {
    return false;
  }
  return true;
}

SANDBOX_TEST(Credentials, NestedUserNS) {
  Credentials creds;
  CHECK(creds.DropAllCapabilities());
  // Probably missing kernel support.
  if (!creds.MoveToNewUserNS()) return;
  creds.DropAllCapabilities();
  // As of 3.12, the kernel has a limit of 32. See create_user_ns().
  const int kNestLevel = 10;
  for (int i = 0; i < kNestLevel; ++i) {
    CHECK(NewUserNSCycle(&creds)) << "Creating new user NS failed at iteration "
                                  << i << ".";
  }
}

// Test the WorkingDirectoryIsRoot() helper.
TEST(Credentials, CanDetectRoot) {
  ASSERT_EQ(0, chdir("/proc/"));
  ASSERT_FALSE(WorkingDirectoryIsRoot());
  ASSERT_EQ(0, chdir("/"));
  ASSERT_TRUE(WorkingDirectoryIsRoot());
}

SANDBOX_TEST(Credentials, DISABLE_ON_LSAN(DropFileSystemAccessIsSafe)) {
  Credentials creds;
  CHECK(creds.DropAllCapabilities());
  // Probably missing kernel support.
  if (!creds.MoveToNewUserNS()) return;
  CHECK(creds.DropFileSystemAccess());
  CHECK(!DirectoryExists("/proc"));
  CHECK(WorkingDirectoryIsRoot());
  // We want the chroot to never have a subdirectory. A subdirectory
  // could allow a chroot escape.
  CHECK_NE(0, mkdir("/test", 0700));
}

// Check that after dropping filesystem access and dropping privileges
// it is not possible to regain capabilities.
SANDBOX_TEST(Credentials, DISABLE_ON_LSAN(CannotRegainPrivileges)) {
  Credentials creds;
  CHECK(creds.DropAllCapabilities());
  // Probably missing kernel support.
  if (!creds.MoveToNewUserNS()) return;
  CHECK(creds.DropFileSystemAccess());
  CHECK(creds.DropAllCapabilities());

  // The kernel should now prevent us from regaining capabilities because we
  // are in a chroot.
  CHECK(!Credentials::SupportsNewUserNS());
  CHECK(!creds.MoveToNewUserNS());
}

}  // namespace.

}  // namespace sandbox.
