| Index: content/common/sandbox_linux/sandbox_debug_handling_linux.cc
|
| diff --git a/content/common/sandbox_linux/sandbox_debug_handling_linux.cc b/content/common/sandbox_linux/sandbox_debug_handling_linux.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0bf8799f0489cf222b690d0723c8e6f64878f3d7
|
| --- /dev/null
|
| +++ b/content/common/sandbox_linux/sandbox_debug_handling_linux.cc
|
| @@ -0,0 +1,79 @@
|
| +// Copyright 2015 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 "content/common/sandbox_linux/sandbox_debug_handling_linux.h"
|
| +
|
| +#include <errno.h>
|
| +#include <signal.h>
|
| +#include <sys/prctl.h>
|
| +#include <unistd.h>
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/logging.h"
|
| +#include "base/macros.h"
|
| +#include "base/strings/safe_sprintf.h"
|
| +#include "content/public/common/content_switches.h"
|
| +
|
| +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 InstallCrashTestHandler() {
|
| + struct sigaction act = {};
|
| + act.sa_handler = DoChrootSignalHandler;
|
| + CHECK_EQ(0, sigemptyset(&act.sa_mask));
|
| + act.sa_flags = 0;
|
| +
|
| + PCHECK(0 == sigaction(SIGUSR2, &act, NULL));
|
| +}
|
| +
|
| +bool IsSandboxDebuggingEnabled() {
|
| + const base::CommandLine& command_line =
|
| + *base::CommandLine::ForCurrentProcess();
|
| + return command_line.HasSwitch(switches::kAllowSandboxDebugging);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +bool SandboxDebugHandling::SetDumpableStatusAndHandlers() {
|
| + if (IsSandboxDebuggingEnabled()) {
|
| + // If sandbox debugging is allowed, install a handler for sandbox-related
|
| + // crash testing.
|
| + InstallCrashTestHandler();
|
| + return true;
|
| + }
|
| +
|
| + if (prctl(PR_SET_DUMPABLE, 0) != 0) {
|
| + PLOG(ERROR) << "Failed to set non-dumpable flag";
|
| + return false;
|
| + }
|
| +
|
| + return prctl(PR_GET_DUMPABLE) == 0;
|
| +}
|
| +
|
| +} // namespace content
|
|
|