sandbox_debug_handling_linux.cc 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "sandbox/policy/linux/sandbox_debug_handling_linux.h"
  5. #include <errno.h>
  6. #include <signal.h>
  7. #include <stddef.h>
  8. #include <sys/prctl.h>
  9. #include <unistd.h>
  10. #include <tuple>
  11. #include "base/command_line.h"
  12. #include "base/logging.h"
  13. #include "base/strings/safe_sprintf.h"
  14. #include "sandbox/policy/switches.h"
  15. namespace sandbox {
  16. namespace policy {
  17. namespace {
  18. void DoChrootSignalHandler(int) {
  19. const int old_errno = errno;
  20. const char kFirstMessage[] = "Chroot signal handler called.\n";
  21. std::ignore = write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1);
  22. const int chroot_ret = chroot("/");
  23. char kSecondMessage[100];
  24. const ssize_t printed = base::strings::SafeSPrintf(
  25. kSecondMessage, "chroot() returned %d. Errno is %d.\n", chroot_ret,
  26. errno);
  27. if (printed > 0 && printed < static_cast<ssize_t>(sizeof(kSecondMessage))) {
  28. std::ignore = write(STDERR_FILENO, kSecondMessage, printed);
  29. }
  30. errno = old_errno;
  31. }
  32. // This is a quick hack to allow testing sandbox crash reports in production
  33. // binaries.
  34. // This installs a signal handler for SIGUSR2 that performs a chroot().
  35. // In most of our BPF policies, it is a "watched" system call which will
  36. // trigger a SIGSYS signal whose handler will crash.
  37. // This has been added during the investigation of https://crbug.com/415842.
  38. void InstallCrashTestHandler() {
  39. struct sigaction act = {};
  40. act.sa_handler = DoChrootSignalHandler;
  41. CHECK_EQ(0, sigemptyset(&act.sa_mask));
  42. act.sa_flags = 0;
  43. PCHECK(0 == sigaction(SIGUSR2, &act, NULL));
  44. }
  45. bool IsSandboxDebuggingEnabled() {
  46. return base::CommandLine::ForCurrentProcess()->HasSwitch(
  47. switches::kAllowSandboxDebugging);
  48. }
  49. } // namespace
  50. // static
  51. bool SandboxDebugHandling::SetDumpableStatusAndHandlers() {
  52. if (IsSandboxDebuggingEnabled()) {
  53. // If sandbox debugging is allowed, install a handler for sandbox-related
  54. // crash testing.
  55. InstallCrashTestHandler();
  56. return true;
  57. }
  58. if (prctl(PR_SET_DUMPABLE, 0) != 0) {
  59. PLOG(ERROR) << "Failed to set non-dumpable flag";
  60. return false;
  61. }
  62. return prctl(PR_GET_DUMPABLE) == 0;
  63. }
  64. } // namespace policy
  65. } // namespace sandbox