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 |