Index: sandbox/linux/services/credentials.cc |
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc |
index 2e66d97cf53a45895d0ea7caeb1e8315f0a510a8..35bb4dcbd73fe99882deaf362dae473b9efd8c56 100644 |
--- a/sandbox/linux/services/credentials.cc |
+++ b/sandbox/linux/services/credentials.cc |
@@ -6,13 +6,13 @@ |
#include <errno.h> |
#include <signal.h> |
+#include <stdint.h> |
#include <stdio.h> |
#include <sys/syscall.h> |
#include <sys/types.h> |
#include <sys/wait.h> |
#include <unistd.h> |
-#include "base/basictypes.h" |
#include "base/bind.h" |
#include "base/files/file_path.h" |
#include "base/files/file_util.h" |
@@ -27,6 +27,7 @@ |
#include "sandbox/linux/services/syscall_wrappers.h" |
#include "sandbox/linux/services/thread_helpers.h" |
#include "sandbox/linux/system_headers/capability.h" |
+#include "sandbox/linux/system_headers/linux_signal.h" |
namespace sandbox { |
@@ -40,8 +41,8 @@ bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; } |
bool GetRESIds(uid_t* resuid, gid_t* resgid) { |
uid_t ruid, euid, suid; |
gid_t rgid, egid, sgid; |
- PCHECK(getresuid(&ruid, &euid, &suid) == 0); |
- PCHECK(getresgid(&rgid, &egid, &sgid) == 0); |
+ PCHECK(sys_getresuid(&ruid, &euid, &suid) == 0); |
+ PCHECK(sys_getresgid(&rgid, &egid, &sgid) == 0); |
const bool uids_are_equal = (ruid == euid) && (ruid == suid); |
const bool gids_are_equal = (rgid == egid) && (rgid == sgid); |
if (!uids_are_equal || !gids_are_equal) return false; |
@@ -53,7 +54,7 @@ bool GetRESIds(uid_t* resuid, gid_t* resgid) { |
const int kExitSuccess = 0; |
int ChrootToSelfFdinfo(void*) { |
- RAW_CHECK(chroot("/proc/self/fdinfo/") == 0); |
+ RAW_CHECK(sys_chroot("/proc/self/fdinfo/") == 0); |
// CWD is essentially an implicit file descriptor, so be careful to not |
// leave it behind. |
@@ -89,9 +90,10 @@ bool ChrootToSafeEmptyDir() { |
#else |
#error "Unsupported architecture" |
#endif |
+ |
pid = clone(ChrootToSelfFdinfo, stack, |
- CLONE_VM | CLONE_VFORK | CLONE_FS | SIGCHLD, nullptr, nullptr, |
- nullptr, nullptr); |
+ CLONE_VM | CLONE_VFORK | CLONE_FS | LINUX_SIGCHLD, nullptr, |
+ nullptr, nullptr, nullptr); |
PCHECK(pid != -1); |
int status = -1; |
@@ -110,23 +112,24 @@ void CheckCloneNewUserErrno(int error) { |
error == ENOSYS); |
} |
-// Converts a LinuxCapability to the corresponding Linux CAP_XXX value. |
-int LinuxCapabilityToKernelValue(LinuxCapability cap) { |
+// Converts a Capability to the corresponding Linux CAP_XXX value. |
+int CapabilityToKernelValue(Credentials::Capability cap) { |
switch (cap) { |
- case LinuxCapability::kCapSysChroot: |
+ case Credentials::Capability::SYS_CHROOT: |
return CAP_SYS_CHROOT; |
- case LinuxCapability::kCapSysAdmin: |
+ case Credentials::Capability::SYS_ADMIN: |
return CAP_SYS_ADMIN; |
} |
- LOG(FATAL) << "Invalid LinuxCapability: " << static_cast<int>(cap); |
+ LOG(FATAL) << "Invalid Capability: " << static_cast<int>(cap); |
return 0; |
} |
} // namespace. |
+// static |
bool Credentials::DropAllCapabilities(int proc_fd) { |
- if (!SetCapabilities(proc_fd, std::vector<LinuxCapability>())) { |
+ if (!SetCapabilities(proc_fd, std::vector<Capability>())) { |
return false; |
} |
@@ -134,30 +137,28 @@ bool Credentials::DropAllCapabilities(int proc_fd) { |
return true; |
} |
+// static |
bool Credentials::DropAllCapabilities() { |
base::ScopedFD proc_fd(ProcUtil::OpenProc()); |
return Credentials::DropAllCapabilities(proc_fd.get()); |
} |
// static |
-bool Credentials::SetCapabilities(int proc_fd, |
- const std::vector<LinuxCapability>& caps) { |
- DCHECK_LE(0, proc_fd); |
- |
-#if !defined(THREAD_SANITIZER) |
- // With TSAN, accept to break the security model as it is a testing |
- // configuration. |
- CHECK(ThreadHelpers::IsSingleThreaded(proc_fd)); |
-#endif |
+bool Credentials::DropAllCapabilitiesOnCurrentThread() { |
+ return SetCapabilitiesOnCurrentThread(std::vector<Capability>()); |
+} |
+// static |
+bool Credentials::SetCapabilitiesOnCurrentThread( |
+ const std::vector<Capability>& caps) { |
struct cap_hdr hdr = {}; |
hdr.version = _LINUX_CAPABILITY_VERSION_3; |
struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; |
// Initially, cap has no capability flags set. Enable the effective and |
// permitted flags only for the requested capabilities. |
- for (const LinuxCapability cap : caps) { |
- const int cap_num = LinuxCapabilityToKernelValue(cap); |
+ for (const Capability cap : caps) { |
+ const int cap_num = CapabilityToKernelValue(cap); |
const size_t index = CAP_TO_INDEX(cap_num); |
const uint32_t mask = CAP_TO_MASK(cap_num); |
data[index].effective |= mask; |
@@ -167,6 +168,20 @@ bool Credentials::SetCapabilities(int proc_fd, |
return sys_capset(&hdr, data) == 0; |
} |
+// static |
+bool Credentials::SetCapabilities(int proc_fd, |
+ const std::vector<Capability>& caps) { |
+ DCHECK_LE(0, proc_fd); |
+ |
+#if !defined(THREAD_SANITIZER) |
+ // With TSAN, accept to break the security model as it is a testing |
+ // configuration. |
+ CHECK(ThreadHelpers::IsSingleThreaded(proc_fd)); |
+#endif |
+ |
+ return SetCapabilitiesOnCurrentThread(caps); |
+} |
+ |
bool Credentials::HasAnyCapability() { |
struct cap_hdr hdr = {}; |
hdr.version = _LINUX_CAPABILITY_VERSION_3; |
@@ -183,14 +198,14 @@ bool Credentials::HasAnyCapability() { |
return false; |
} |
-bool Credentials::HasCapability(LinuxCapability cap) { |
+bool Credentials::HasCapability(Capability cap) { |
struct cap_hdr hdr = {}; |
hdr.version = _LINUX_CAPABILITY_VERSION_3; |
struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; |
PCHECK(sys_capget(&hdr, data) == 0); |
- const int cap_num = LinuxCapabilityToKernelValue(cap); |
+ const int cap_num = CapabilityToKernelValue(cap); |
const size_t index = CAP_TO_INDEX(cap_num); |
const uint32_t mask = CAP_TO_MASK(cap_num); |
@@ -247,7 +262,7 @@ bool Credentials::MoveToNewUserNS() { |
DVLOG(1) << "uids or gids differ!"; |
return false; |
} |
- int ret = unshare(CLONE_NEWUSER); |
+ int ret = sys_unshare(CLONE_NEWUSER); |
if (ret) { |
const int unshare_errno = errno; |
VLOG(1) << "Looks like unprivileged CLONE_NEWUSER may not be available " |