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 "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> |
11 #include <errno.h> | 11 #include <errno.h> |
12 #include <fcntl.h> | 12 #include <fcntl.h> |
13 #include <limits.h> | 13 #include <limits.h> |
14 #include <sched.h> | 14 #include <sched.h> |
15 #include <signal.h> | 15 #include <signal.h> |
16 #include <stdarg.h> | 16 #include <stdarg.h> |
17 #include <stdbool.h> | 17 #include <stdbool.h> |
18 #include <stdint.h> | 18 #include <stdint.h> |
19 #include <stdio.h> | 19 #include <stdio.h> |
20 #include <stdlib.h> | 20 #include <stdlib.h> |
21 #include <string.h> | 21 #include <string.h> |
22 #include <sys/prctl.h> | 22 #include <sys/prctl.h> |
23 #include <sys/resource.h> | 23 #include <sys/resource.h> |
24 #include <sys/socket.h> | 24 #include <sys/socket.h> |
25 #include <sys/stat.h> | 25 #include <sys/stat.h> |
26 #include <sys/time.h> | 26 #include <sys/time.h> |
27 #include <sys/types.h> | 27 #include <sys/types.h> |
28 #include <sys/vfs.h> | 28 #include <sys/vfs.h> |
29 #include <sys/wait.h> | 29 #include <sys/wait.h> |
30 #include <unistd.h> | 30 #include <unistd.h> |
31 | 31 |
32 #include "linux_util.h" | 32 #include "linux_util.h" |
33 #include "process_util.h" | 33 #include "process_util.h" |
34 #include "suid_unsafe_environment_variables.h" | 34 #include "common/suid_unsafe_environment_variables.h" |
35 | 35 |
36 #if !defined(CLONE_NEWPID) | 36 #if !defined(CLONE_NEWPID) |
37 #define CLONE_NEWPID 0x20000000 | 37 #define CLONE_NEWPID 0x20000000 |
38 #endif | 38 #endif |
39 #if !defined(CLONE_NEWNET) | 39 #if !defined(CLONE_NEWNET) |
40 #define CLONE_NEWNET 0x40000000 | 40 #define CLONE_NEWNET 0x40000000 |
41 #endif | 41 #endif |
42 | 42 |
43 static const char kSandboxDescriptorEnvironmentVarName[] = "SBX_D"; | |
44 static const char kSandboxHelperPidEnvironmentVarName[] = "SBX_HELPER_PID"; | |
45 | |
46 // Should be kept in sync with base/linux_util.h | |
47 static const long kSUIDSandboxApiNumber = 1; | |
48 static const char kSandboxEnvironmentApiRequest[] = "SBX_CHROME_API_RQ"; | |
49 static const char kSandboxEnvironmentApiProvides[] = "SBX_CHROME_API_PRV"; | |
50 | |
51 // This number must be kept in sync with common/zygote_commands_linux.h | |
52 static const int kZygoteIdFd = 7; | |
53 | |
54 // These are the magic byte values which the sandboxed process uses to request | |
55 // that it be chrooted. | |
56 static const char kMsgChrootMe = 'C'; | |
57 static const char kMsgChrootSuccessful = 'O'; | |
58 | |
59 static bool DropRoot(); | 43 static bool DropRoot(); |
60 | 44 |
61 #define HANDLE_EINTR(x) TEMP_FAILURE_RETRY(x) | 45 #define HANDLE_EINTR(x) TEMP_FAILURE_RETRY(x) |
62 | 46 |
63 static void FatalError(const char *msg, ...) | 47 static void FatalError(const char *msg, ...) |
64 __attribute__((noreturn, format(printf, 1, 2))); | 48 __attribute__((noreturn, format(printf, 1, 2))); |
65 | 49 |
66 static void FatalError(const char *msg, ...) { | 50 static void FatalError(const char *msg, ...) { |
67 va_list ap; | 51 va_list ap; |
68 va_start(ap, msg); | 52 va_start(ap, msg); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 257 |
274 // Wait for the parent to confirm it closed kZygoteIdFd before we | 258 // Wait for the parent to confirm it closed kZygoteIdFd before we |
275 // continue | 259 // continue |
276 char should_continue; | 260 char should_continue; |
277 if (HANDLE_EINTR(read(sync_fds[0], &should_continue, 1)) != 1) | 261 if (HANDLE_EINTR(read(sync_fds[0], &should_continue, 1)) != 1) |
278 FatalError("Read on socketpair"); | 262 FatalError("Read on socketpair"); |
279 if (close(sync_fds[0])) | 263 if (close(sync_fds[0])) |
280 FatalError("close"); | 264 FatalError("close"); |
281 | 265 |
282 if (kCloneExtraFlags[i] & CLONE_NEWPID) { | 266 if (kCloneExtraFlags[i] & CLONE_NEWPID) { |
283 setenv("SBX_PID_NS", "", 1 /* overwrite */); | 267 setenv(kSandboxPIDNSEnvironmentVarName, "", 1 /* overwrite */); |
284 } else { | 268 } else { |
285 unsetenv("SBX_PID_NS"); | 269 unsetenv(kSandboxPIDNSEnvironmentVarName); |
286 } | 270 } |
287 | 271 |
288 if (kCloneExtraFlags[i] & CLONE_NEWNET) { | 272 if (kCloneExtraFlags[i] & CLONE_NEWNET) { |
289 setenv("SBX_NET_NS", "", 1 /* overwrite */); | 273 setenv(kSandboxNETNSEnvironmentVarName, "", 1 /* overwrite */); |
290 } else { | 274 } else { |
291 unsetenv("SBX_NET_NS"); | 275 unsetenv(kSandboxNETNSEnvironmentVarName); |
292 } | 276 } |
293 | 277 |
294 break; | 278 break; |
295 } | 279 } |
296 | 280 |
297 if (errno != EINVAL) { | 281 if (errno != EINVAL) { |
298 perror("Failed to move to new PID namespace"); | 282 perror("Failed to move to new PID namespace"); |
299 return false; | 283 return false; |
300 } | 284 } |
301 } | 285 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 if (!DropRoot()) | 473 if (!DropRoot()) |
490 return 1; | 474 return 1; |
491 if (!SetupChildEnvironment()) | 475 if (!SetupChildEnvironment()) |
492 return 1; | 476 return 1; |
493 | 477 |
494 execv(argv[1], &argv[1]); | 478 execv(argv[1], &argv[1]); |
495 FatalError("execv failed"); | 479 FatalError("execv failed"); |
496 | 480 |
497 return 1; | 481 return 1; |
498 } | 482 } |
OLD | NEW |