Index: content/zygote/zygote_main_linux.cc |
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc |
index b77471a88d956a5fae66617ba90718fa4e187460..361511e37374cee7b9546059d05fb8f2405ad411 100644 |
--- a/content/zygote/zygote_main_linux.cc |
+++ b/content/zygote/zygote_main_linux.cc |
@@ -7,6 +7,7 @@ |
#include <dlfcn.h> |
#include <fcntl.h> |
#include <pthread.h> |
+#include <signal.h> |
#include <string.h> |
#include <sys/socket.h> |
#include <sys/types.h> |
@@ -22,6 +23,7 @@ |
#include "base/posix/eintr_wrapper.h" |
#include "base/posix/unix_domain_socket_linux.h" |
#include "base/rand_util.h" |
+#include "base/strings/safe_sprintf.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/sys_info.h" |
#include "build/build_config.h" |
@@ -64,6 +66,43 @@ |
namespace content { |
+namespace { |
+ |
+void DoChrootSignalHandler(int) { |
+ const int old_errno = errno; |
+ const char kFirstMessage[] = "Chroot signal handler called.\n"; |
+ ignore_result(write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1)); |
+ |
+ const int chroot_ret = chroot("/"); |
+ |
+ char kSecondMessage[100]; |
+ const ssize_t printed = |
+ base::strings::SafeSPrintf(kSecondMessage, |
+ "chroot() returned %d. Errno is %d.\n", |
+ chroot_ret, |
+ errno); |
+ if (printed > 0 && printed < static_cast<ssize_t>(sizeof(kSecondMessage))) { |
+ ignore_result(write(STDERR_FILENO, kSecondMessage, printed)); |
+ } |
+ errno = old_errno; |
+} |
+ |
+// This is a quick hack to allow testing sandbox crash reports in production |
+// binaries. |
+// This installs a signal handler for SIGUSR2 that performs a chroot(). |
+// In most of our BPF policies, it is a "watched" system call which will |
+// trigger a SIGSYS signal whose handler will crash. |
+// This has been added during the investigation of https://crbug.com/415842. |
+void InstallSandboxCrashTestHandler() { |
+ struct sigaction act = {}; |
+ act.sa_handler = DoChrootSignalHandler; |
+ CHECK_EQ(0, sigemptyset(&act.sa_mask)); |
+ act.sa_flags = 0; |
+ |
+ PCHECK(0 == sigaction(SIGUSR2, &act, NULL)); |
+} |
+} // namespace |
+ |
// See http://code.google.com/p/chromium/wiki/LinuxZygote |
static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, |
@@ -410,7 +449,12 @@ static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, |
LOG(ERROR) << "Failed to set non-dumpable flag"; |
return false; |
} |
+ } else { |
+ // If sandbox debugging is allowed, install a handler for sandbox-related |
+ // crash testing. |
+ InstallSandboxCrashTestHandler(); |
} |
+ |
#endif |
return true; |