Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Unified Diff: sandbox/linux/services/credentials.cc

Issue 863933004: Linux sandbox: Make ChrootToSafeEmptyDir() faster. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sandbox/linux/services/credentials_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/linux/services/credentials.cc
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index 291c2cad4450e9a473281255cde6b72009c3852f..be03e15ac78382b9280a3610df41b5eed0cac02c 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -24,6 +24,8 @@
#include "base/third_party/valgrind/valgrind.h"
#include "sandbox/linux/services/syscall_wrappers.h"
+namespace sandbox {
+
namespace {
bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; }
@@ -97,6 +99,17 @@ bool GetRESIds(uid_t* resuid, gid_t* resgid) {
return true;
}
+const int kExitSuccess = 0;
+
+int ChrootToSelfFdinfo(void*) {
+ RAW_CHECK(chroot("/proc/self/fdinfo/") == 0);
+
+ // CWD is essentially an implicit file descriptor, so be careful to not
+ // leave it behind.
+ RAW_CHECK(chdir("/") == 0);
+ _exit(kExitSuccess);
+}
+
// chroot() to an empty dir that is "safe". To be safe, it must not contain
// any subdirectory (chroot-ing there would allow a chroot escape) and it must
// be impossible to create an empty directory there.
@@ -108,25 +121,32 @@ bool GetRESIds(uid_t* resuid, gid_t* resgid) {
// 3. The process dies
// After (3) happens, the directory is not available anymore in /proc.
bool ChrootToSafeEmptyDir() {
- // We do not use a thread because when we are in a PID namespace, we cannot
- // easily get a handle to the /proc/tid directory for the thread (since /proc
- // may not be aware of the PID namespace). With a process, we can just use
- // /proc/self.
- pid_t pid = base::ForkWithFlags(SIGCHLD | CLONE_FS, nullptr, nullptr);
+ // We need to chroot to a fdinfo that is unique to a process and have that
+ // process die.
+ // 1. We don't want to simply fork() because duplicating the page tables is
+ // slow with a big address space.
+ // 2. We do not use a regular thread (that would unshare CLONE_FILES) because
+ // when we are in a PID namespace, we cannot easily get a handle to the
+ // /proc/tid directory for the thread (since /proc may not be aware of the
+ // PID namespace). With a process, we can just use /proc/self.
+ pid_t pid = -1;
+ char stack_buf[PTHREAD_STACK_MIN];
+#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
+ defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
+ // The stack grows downward.
+ void* stack = stack_buf + sizeof(stack_buf);
+#else
+#error "Unsupported architecture"
+#endif
+ pid = clone(ChrootToSelfFdinfo, stack,
+ CLONE_VM | CLONE_VFORK | CLONE_FS | SIGCHLD, nullptr, nullptr,
+ nullptr, nullptr);
PCHECK(pid != -1);
- if (pid == 0) {
- RAW_CHECK(chroot("/proc/self/fdinfo/") == 0);
-
- // CWD is essentially an implicit file descriptor, so be careful to not
- // leave it behind.
- RAW_CHECK(chdir("/") == 0);
- _exit(0);
- }
int status = -1;
PCHECK(HANDLE_EINTR(waitpid(pid, &status, 0)) == pid);
- return status == 0;
+ return kExitSuccess == status;
}
// CHECK() that an attempt to move to a new user namespace raised an expected
@@ -141,8 +161,6 @@ void CheckCloneNewUserErrno(int error) {
} // namespace.
-namespace sandbox {
-
bool Credentials::DropAllCapabilities() {
ScopedCap cap(cap_init());
CHECK(cap);
« no previous file with comments | « no previous file | sandbox/linux/services/credentials_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698