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

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

Issue 188193002: Linux sandbox: add basic Yama support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Add testing. Created 6 years, 9 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
Index: sandbox/linux/services/scoped_process.cc
diff --git a/sandbox/linux/services/scoped_process.cc b/sandbox/linux/services/scoped_process.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b337812b5be45e9f21eb9279ba4e75d386ae62d9
--- /dev/null
+++ b/sandbox/linux/services/scoped_process.cc
@@ -0,0 +1,77 @@
+// Copyright 2014 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/scoped_process.h"
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "sandbox/linux/services/thread_helpers.h"
+
+namespace sandbox {
+
+ScopedProcess::ScopedProcess(const base::Closure& child_callback)
+ : child_callback_(child_callback),
+ child_process_id_(-1),
+ process_id_(getpid()) {
+ // Make sure that we can safely fork().
+ CHECK(ThreadHelpers::IsSingleThreaded(-1));
+ child_process_id_ = fork();
+ PCHECK(0 <= child_process_id_);
+ if (0 == child_process_id_) {
+ child_callback_.Run();
+ _exit(0);
+ }
+}
+
+ScopedProcess::~ScopedProcess() {
+ CHECK(IsOriginalProcess());
+ if (child_process_id_ >= 0) {
+ PCHECK(0 == kill(child_process_id_, SIGKILL));
+ siginfo_t process_info;
+
+ PCHECK(0 == HANDLE_EINTR(
+ waitid(P_PID, child_process_id_, &process_info, WEXITED)));
+ }
+}
+
+int ScopedProcess::WaitForExit(bool* got_signaled) {
+ DCHECK(got_signaled);
+ CHECK(IsOriginalProcess());
+ siginfo_t process_info;
+ // WNOWAIT to make sure that the destructor can wait on the child.
+ int ret = HANDLE_EINTR(
+ waitid(P_PID, child_process_id_, &process_info, WEXITED | WNOWAIT));
+ PCHECK(0 == ret) << "Did something else wait on the child?";
+
+ if (process_info.si_code == CLD_EXITED) {
+ *got_signaled = false;
+ } else if (process_info.si_code == CLD_KILLED ||
+ process_info.si_code == CLD_DUMPED) {
+ *got_signaled = true;
+ } else {
+ CHECK(false) << "ScopedProcess needs to be extended for si_code "
+ << process_info.si_code;
+ }
+ return process_info.si_status;
+}
+
+// It would be problematic if after a fork(), another process would start using
+// this object.
+// This method allows to assert it is not happening.
+bool ScopedProcess::IsOriginalProcess() {
+ // Make a direct syscall to bypass glibc caching of PIDs.
+ int pid = syscall(__NR_getpid);
+ return pid == process_id_;
+}
+
+} // namespace sandbox

Powered by Google App Engine
This is Rietveld 408576698