| Index: sandbox/linux/services/credentials_unittest.cc
|
| diff --git a/sandbox/linux/services/credentials_unittest.cc b/sandbox/linux/services/credentials_unittest.cc
|
| index 2884e740afef10e3aca7daf1b7cafa1f893bc118..db19f6fee561073c1dc7a0f0ba7dfc29b91abd65 100644
|
| --- a/sandbox/linux/services/credentials_unittest.cc
|
| +++ b/sandbox/linux/services/credentials_unittest.cc
|
| @@ -7,16 +7,21 @@
|
| #include <errno.h>
|
| #include <fcntl.h>
|
| #include <stdio.h>
|
| +#include <sys/capability.h>
|
| #include <sys/stat.h>
|
| #include <sys/types.h>
|
| #include <unistd.h>
|
|
|
| +#include <vector>
|
| +
|
| #include "base/files/file_path.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/services/proc_util.h"
|
| +#include "sandbox/linux/services/syscall_wrappers.h"
|
| +#include "sandbox/linux/system_headers/capability.h"
|
| #include "sandbox/linux/tests/unit_tests.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -24,6 +29,16 @@ namespace sandbox {
|
|
|
| namespace {
|
|
|
| +struct CapFreeDeleter {
|
| + inline void operator()(cap_t cap) const {
|
| + int ret = cap_free(cap);
|
| + CHECK_EQ(0, ret);
|
| + }
|
| +};
|
| +
|
| +// Wrapper to manage libcap2's cap_t type.
|
| +typedef scoped_ptr<typeof(*((cap_t)0)), CapFreeDeleter> ScopedCap;
|
| +
|
| bool WorkingDirectoryIsRoot() {
|
| char current_dir[PATH_MAX];
|
| char* cwd = getcwd(current_dir, sizeof(current_dir));
|
| @@ -48,12 +63,6 @@ SANDBOX_TEST(Credentials, DropAllCaps) {
|
| CHECK(!Credentials::HasAnyCapability());
|
| }
|
|
|
| -SANDBOX_TEST(Credentials, GetCurrentCapString) {
|
| - CHECK(Credentials::DropAllCapabilities());
|
| - const char kNoCapabilityText[] = "=";
|
| - CHECK(*Credentials::GetCurrentCapString() == kNoCapabilityText);
|
| -}
|
| -
|
| SANDBOX_TEST(Credentials, MoveToNewUserNS) {
|
| CHECK(Credentials::DropAllCapabilities());
|
| bool moved_to_new_ns = Credentials::MoveToNewUserNS();
|
| @@ -161,6 +170,70 @@ SANDBOX_TEST(Credentials, DISABLE_ON_ASAN(CannotRegainPrivileges)) {
|
| CHECK(!Credentials::MoveToNewUserNS());
|
| }
|
|
|
| +SANDBOX_TEST(Credentials, SetCapabilities) {
|
| + // Probably missing kernel support.
|
| + if (!Credentials::MoveToNewUserNS())
|
| + return;
|
| +
|
| + base::ScopedFD proc_fd(ProcUtil::OpenProc());
|
| +
|
| + CHECK(Credentials::HasCapability(LinuxCapability::kCapSysAdmin));
|
| + CHECK(Credentials::HasCapability(LinuxCapability::kCapSysChroot));
|
| +
|
| + const std::vector<LinuxCapability> caps = {LinuxCapability::kCapSysChroot};
|
| + CHECK(Credentials::SetCapabilities(proc_fd.get(), caps));
|
| +
|
| + CHECK(!Credentials::HasCapability(LinuxCapability::kCapSysAdmin));
|
| + CHECK(Credentials::HasCapability(LinuxCapability::kCapSysChroot));
|
| +
|
| + const std::vector<LinuxCapability> no_caps;
|
| + CHECK(Credentials::SetCapabilities(proc_fd.get(), no_caps));
|
| + CHECK(!Credentials::HasAnyCapability());
|
| +}
|
| +
|
| +SANDBOX_TEST(Credentials, SetCapabilitiesAndChroot) {
|
| + // Probably missing kernel support.
|
| + if (!Credentials::MoveToNewUserNS())
|
| + return;
|
| +
|
| + base::ScopedFD proc_fd(ProcUtil::OpenProc());
|
| +
|
| + CHECK(Credentials::HasCapability(LinuxCapability::kCapSysChroot));
|
| + PCHECK(chroot("/") == 0);
|
| +
|
| + const std::vector<LinuxCapability> caps = {LinuxCapability::kCapSysChroot};
|
| + CHECK(Credentials::SetCapabilities(proc_fd.get(), caps));
|
| + PCHECK(chroot("/") == 0);
|
| +
|
| + CHECK(Credentials::DropAllCapabilities());
|
| + PCHECK(chroot("/") == -1 && errno == EPERM);
|
| +}
|
| +
|
| +SANDBOX_TEST(Credentials, SetCapabilitiesMatchesLibCap2) {
|
| + // Probably missing kernel support.
|
| + if (!Credentials::MoveToNewUserNS())
|
| + return;
|
| +
|
| + base::ScopedFD proc_fd(ProcUtil::OpenProc());
|
| +
|
| + const std::vector<LinuxCapability> caps = {LinuxCapability::kCapSysChroot};
|
| + CHECK(Credentials::SetCapabilities(proc_fd.get(), caps));
|
| +
|
| + ScopedCap actual_cap(cap_get_proc());
|
| + PCHECK(actual_cap != nullptr);
|
| +
|
| + ScopedCap expected_cap(cap_init());
|
| + PCHECK(expected_cap != nullptr);
|
| +
|
| + const cap_value_t allowed_cap = CAP_SYS_CHROOT;
|
| + for (const cap_flag_t flag : {CAP_EFFECTIVE, CAP_PERMITTED}) {
|
| + PCHECK(cap_set_flag(expected_cap.get(), flag, 1, &allowed_cap, CAP_SET) ==
|
| + 0);
|
| + }
|
| +
|
| + CHECK_EQ(0, cap_compare(expected_cap.get(), actual_cap.get()));
|
| +}
|
| +
|
| } // namespace.
|
|
|
| } // namespace sandbox.
|
|
|