| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox | 5 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox |
| 6 | 6 |
| 7 #include "common/sandbox.h" | 7 #include "common/sandbox.h" |
| 8 | 8 |
| 9 #define _GNU_SOURCE | 9 #define _GNU_SOURCE |
| 10 #include <asm/unistd.h> | 10 #include <asm/unistd.h> |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 va_list ap; | 51 va_list ap; |
| 52 va_start(ap, msg); | 52 va_start(ap, msg); |
| 53 | 53 |
| 54 vfprintf(stderr, msg, ap); | 54 vfprintf(stderr, msg, ap); |
| 55 fprintf(stderr, ": %s\n", strerror(errno)); | 55 fprintf(stderr, ": %s\n", strerror(errno)); |
| 56 fflush(stderr); | 56 fflush(stderr); |
| 57 va_end(ap); | 57 va_end(ap); |
| 58 _exit(1); | 58 _exit(1); |
| 59 } | 59 } |
| 60 | 60 |
| 61 static void ExitWithErrorSignalHandler(int signal) { | |
| 62 const char msg[] = "\nThe setuid sandbox got signaled, exiting.\n"; | |
| 63 (void) write(2, msg, sizeof(msg) - 1); | |
| 64 _exit(1); | |
| 65 } | |
| 66 | |
| 67 // We will chroot() to the helper's /proc/self directory. Anything there will | 61 // We will chroot() to the helper's /proc/self directory. Anything there will |
| 68 // not exist anymore if we make sure to wait() for the helper. | 62 // not exist anymore if we make sure to wait() for the helper. |
| 69 // | 63 // |
| 70 // /proc/self/fdinfo or /proc/self/fd are especially safe and will be empty | 64 // /proc/self/fdinfo or /proc/self/fd are especially safe and will be empty |
| 71 // even if the helper survives as a zombie. | 65 // even if the helper survives as a zombie. |
| 72 // | 66 // |
| 73 // There is very little reason to use fdinfo/ instead of fd/ but we are | 67 // There is very little reason to use fdinfo/ instead of fd/ but we are |
| 74 // paranoid. fdinfo/ only exists since 2.6.22 so we allow fallback to fd/ | 68 // paranoid. fdinfo/ only exists since 2.6.22 so we allow fallback to fd/ |
| 75 #define SAFE_DIR "/proc/self/fdinfo" | 69 #define SAFE_DIR "/proc/self/fdinfo" |
| 76 #define SAFE_DIR2 "/proc/self/fd" | 70 #define SAFE_DIR2 "/proc/self/fd" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 } | 188 } |
| 195 | 189 |
| 196 return true; | 190 return true; |
| 197 } | 191 } |
| 198 | 192 |
| 199 // Block until child_pid exits, then exit. Try to preserve the exit code. | 193 // Block until child_pid exits, then exit. Try to preserve the exit code. |
| 200 static void WaitForChildAndExit(pid_t child_pid) { | 194 static void WaitForChildAndExit(pid_t child_pid) { |
| 201 int exit_code = -1; | 195 int exit_code = -1; |
| 202 siginfo_t reaped_child_info; | 196 siginfo_t reaped_child_info; |
| 203 | 197 |
| 204 // Don't "Core" on SIGABRT. SIGABRT is sent by the Chrome OS session manager | |
| 205 // when things are hanging. | |
| 206 // Here, the current process is going to waitid() and _exit(), so there is no | |
| 207 // point in generating a crash report. The child process is the one | |
| 208 // blocking us. | |
| 209 if (signal(SIGABRT, ExitWithErrorSignalHandler) == SIG_ERR) { | |
| 210 FatalError("Failed to change signal handler"); | |
| 211 } | |
| 212 | |
| 213 int wait_ret = | 198 int wait_ret = |
| 214 HANDLE_EINTR(waitid(P_PID, child_pid, &reaped_child_info, WEXITED)); | 199 HANDLE_EINTR(waitid(P_PID, child_pid, &reaped_child_info, WEXITED)); |
| 215 | 200 |
| 216 if (!wait_ret && reaped_child_info.si_pid == child_pid) { | 201 if (!wait_ret && reaped_child_info.si_pid == child_pid) { |
| 217 if (reaped_child_info.si_code == CLD_EXITED) { | 202 if (reaped_child_info.si_code == CLD_EXITED) { |
| 218 exit_code = reaped_child_info.si_status; | 203 exit_code = reaped_child_info.si_status; |
| 219 } else { | 204 } else { |
| 220 // Exit with code 0 if the child got signaled. | 205 // Exit with code 0 if the child got signaled. |
| 221 exit_code = 0; | 206 exit_code = 0; |
| 222 } | 207 } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 if (!DropRoot()) | 475 if (!DropRoot()) |
| 491 return 1; | 476 return 1; |
| 492 if (!SetupChildEnvironment()) | 477 if (!SetupChildEnvironment()) |
| 493 return 1; | 478 return 1; |
| 494 | 479 |
| 495 execv(argv[1], &argv[1]); | 480 execv(argv[1], &argv[1]); |
| 496 FatalError("execv failed"); | 481 FatalError("execv failed"); |
| 497 | 482 |
| 498 return 1; | 483 return 1; |
| 499 } | 484 } |
| OLD | NEW |