| 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 |
| 61 // We will chroot() to the helper's /proc/self directory. Anything there will | 67 // We will chroot() to the helper's /proc/self directory. Anything there will |
| 62 // not exist anymore if we make sure to wait() for the helper. | 68 // not exist anymore if we make sure to wait() for the helper. |
| 63 // | 69 // |
| 64 // /proc/self/fdinfo or /proc/self/fd are especially safe and will be empty | 70 // /proc/self/fdinfo or /proc/self/fd are especially safe and will be empty |
| 65 // even if the helper survives as a zombie. | 71 // even if the helper survives as a zombie. |
| 66 // | 72 // |
| 67 // There is very little reason to use fdinfo/ instead of fd/ but we are | 73 // There is very little reason to use fdinfo/ instead of fd/ but we are |
| 68 // paranoid. fdinfo/ only exists since 2.6.22 so we allow fallback to fd/ | 74 // paranoid. fdinfo/ only exists since 2.6.22 so we allow fallback to fd/ |
| 69 #define SAFE_DIR "/proc/self/fdinfo" | 75 #define SAFE_DIR "/proc/self/fdinfo" |
| 70 #define SAFE_DIR2 "/proc/self/fd" | 76 #define SAFE_DIR2 "/proc/self/fd" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } | 194 } |
| 189 | 195 |
| 190 return true; | 196 return true; |
| 191 } | 197 } |
| 192 | 198 |
| 193 // Block until child_pid exits, then exit. Try to preserve the exit code. | 199 // Block until child_pid exits, then exit. Try to preserve the exit code. |
| 194 static void WaitForChildAndExit(pid_t child_pid) { | 200 static void WaitForChildAndExit(pid_t child_pid) { |
| 195 int exit_code = -1; | 201 int exit_code = -1; |
| 196 siginfo_t reaped_child_info; | 202 siginfo_t reaped_child_info; |
| 197 | 203 |
| 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 |
| 198 int wait_ret = | 213 int wait_ret = |
| 199 HANDLE_EINTR(waitid(P_PID, child_pid, &reaped_child_info, WEXITED)); | 214 HANDLE_EINTR(waitid(P_PID, child_pid, &reaped_child_info, WEXITED)); |
| 200 | 215 |
| 201 if (!wait_ret && reaped_child_info.si_pid == child_pid) { | 216 if (!wait_ret && reaped_child_info.si_pid == child_pid) { |
| 202 if (reaped_child_info.si_code == CLD_EXITED) { | 217 if (reaped_child_info.si_code == CLD_EXITED) { |
| 203 exit_code = reaped_child_info.si_status; | 218 exit_code = reaped_child_info.si_status; |
| 204 } else { | 219 } else { |
| 205 // Exit with code 0 if the child got signaled. | 220 // Exit with code 0 if the child got signaled. |
| 206 exit_code = 0; | 221 exit_code = 0; |
| 207 } | 222 } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 if (!DropRoot()) | 490 if (!DropRoot()) |
| 476 return 1; | 491 return 1; |
| 477 if (!SetupChildEnvironment()) | 492 if (!SetupChildEnvironment()) |
| 478 return 1; | 493 return 1; |
| 479 | 494 |
| 480 execv(argv[1], &argv[1]); | 495 execv(argv[1], &argv[1]); |
| 481 FatalError("execv failed"); | 496 FatalError("execv failed"); |
| 482 | 497 |
| 483 return 1; | 498 return 1; |
| 484 } | 499 } |
| OLD | NEW |