OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #define _GNU_SOURCE | 7 #define _GNU_SOURCE |
8 #include <asm/unistd.h> | 8 #include <asm/unistd.h> |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 return -1; | 83 return -1; |
84 } | 84 } |
85 | 85 |
86 // Some people mount /tmp on a non-POSIX filesystem (e.g. NFS). This | 86 // Some people mount /tmp on a non-POSIX filesystem (e.g. NFS). This |
87 // breaks all sorts of assumption in our code. So, if we don't recognize the | 87 // breaks all sorts of assumption in our code. So, if we don't recognize the |
88 // filesystem, we will try to use an alternative location for our temp | 88 // filesystem, we will try to use an alternative location for our temp |
89 // directory. | 89 // directory. |
90 char tempDirectoryTemplate[80] = "/tmp/chrome-sandbox-chroot-XXXXXX"; | 90 char tempDirectoryTemplate[80] = "/tmp/chrome-sandbox-chroot-XXXXXX"; |
91 struct statfs sfs; | 91 struct statfs sfs; |
92 if (!statfs("/tmp", &sfs) && | 92 if (!statfs("/tmp", &sfs) && |
93 sfs.f_type != BTRFS_SUPER_MAGIC && | 93 (unsigned long)sfs.f_type != BTRFS_SUPER_MAGIC && |
94 sfs.f_type != EXT2_SUPER_MAGIC && | 94 (unsigned long)sfs.f_type != EXT2_SUPER_MAGIC && |
95 sfs.f_type != EXT3_SUPER_MAGIC && | 95 (unsigned long)sfs.f_type != EXT3_SUPER_MAGIC && |
96 sfs.f_type != EXT4_SUPER_MAGIC && | 96 (unsigned long)sfs.f_type != EXT4_SUPER_MAGIC && |
97 sfs.f_type != REISERFS_SUPER_MAGIC && | 97 (unsigned long)sfs.f_type != REISERFS_SUPER_MAGIC && |
98 sfs.f_type != TMPFS_MAGIC && | 98 (unsigned long)sfs.f_type != TMPFS_MAGIC && |
99 sfs.f_type != XFS_SUPER_MAGIC) { | 99 (unsigned long)sfs.f_type != XFS_SUPER_MAGIC) { |
100 // If /dev/shm exists, it is supposed to be a tmpfs filesystem. While we | 100 // If /dev/shm exists, it is supposed to be a tmpfs filesystem. While we |
101 // are not actually using it for shared memory, moving our temp directory | 101 // are not actually using it for shared memory, moving our temp directory |
102 // into a known tmpfs filesystem is preferable over using a potentially | 102 // into a known tmpfs filesystem is preferable over using a potentially |
103 // unreliable non-POSIX filesystem. | 103 // unreliable non-POSIX filesystem. |
104 if (!statfs("/dev/shm", &sfs) && sfs.f_type == TMPFS_MAGIC) { | 104 if (!statfs("/dev/shm", &sfs) && sfs.f_type == TMPFS_MAGIC) { |
105 *tempDirectoryTemplate = '\000'; | 105 *tempDirectoryTemplate = '\000'; |
106 strncat(tempDirectoryTemplate, "/dev/shm/chrome-sandbox-chroot-XXXXXX", | 106 strncat(tempDirectoryTemplate, "/dev/shm/chrome-sandbox-chroot-XXXXXX", |
107 sizeof(tempDirectoryTemplate) - 1); | 107 sizeof(tempDirectoryTemplate) - 1); |
108 } else { | 108 } else { |
109 // Neither /tmp is a well-known POSIX filesystem, nor /dev/shm is a | 109 // Neither /tmp is a well-known POSIX filesystem, nor /dev/shm is a |
(...skipping 20 matching lines...) Expand all Loading... |
130 } | 130 } |
131 | 131 |
132 if (rmdir(temp_dir)) { | 132 if (rmdir(temp_dir)) { |
133 perror("rmdir"); | 133 perror("rmdir"); |
134 return -1; | 134 return -1; |
135 } | 135 } |
136 | 136 |
137 char proc_self_fd_str[128]; | 137 char proc_self_fd_str[128]; |
138 int printed = snprintf(proc_self_fd_str, sizeof(proc_self_fd_str), | 138 int printed = snprintf(proc_self_fd_str, sizeof(proc_self_fd_str), |
139 "/proc/self/fd/%d", chroot_dir_fd); | 139 "/proc/self/fd/%d", chroot_dir_fd); |
140 if (printed < 0 || printed >= sizeof(proc_self_fd_str)) { | 140 if (printed < 0 || printed >= (int)sizeof(proc_self_fd_str)) { |
141 fprintf(stderr, "Error in snprintf"); | 141 fprintf(stderr, "Error in snprintf"); |
142 return -1; | 142 return -1; |
143 } | 143 } |
144 | 144 |
145 if (fchown(chroot_dir_fd, 0 /* root */, 0 /* root */)) { | 145 if (fchown(chroot_dir_fd, 0 /* root */, 0 /* root */)) { |
146 fprintf(stderr, "Could not set up sandbox work directory. Maybe, /tmp is " | 146 fprintf(stderr, "Could not set up sandbox work directory. Maybe, /tmp is " |
147 "a non-POSIX filesystem and /dev/shm doesn't exist " | 147 "a non-POSIX filesystem and /dev/shm doesn't exist " |
148 "either. Consider mounting a \"tmpfs\" on /tmp.\n"); | 148 "either. Consider mounting a \"tmpfs\" on /tmp.\n"); |
149 return -1; | 149 return -1; |
150 } | 150 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 static bool SpawnChrootHelper() { | 239 static bool SpawnChrootHelper() { |
240 const int chroot_signal_fd = CloneChrootHelperProcess(); | 240 const int chroot_signal_fd = CloneChrootHelperProcess(); |
241 | 241 |
242 if (chroot_signal_fd == -1) | 242 if (chroot_signal_fd == -1) |
243 return false; | 243 return false; |
244 | 244 |
245 // In the parent process, we install an environment variable containing the | 245 // In the parent process, we install an environment variable containing the |
246 // number of the file descriptor. | 246 // number of the file descriptor. |
247 char desc_str[64]; | 247 char desc_str[64]; |
248 int printed = snprintf(desc_str, sizeof(desc_str), "%d", chroot_signal_fd); | 248 int printed = snprintf(desc_str, sizeof(desc_str), "%d", chroot_signal_fd); |
249 if (printed < 0 || printed >= sizeof(desc_str)) { | 249 if (printed < 0 || printed >= (int)sizeof(desc_str)) { |
250 fprintf(stderr, "Failed to snprintf\n"); | 250 fprintf(stderr, "Failed to snprintf\n"); |
251 return false; | 251 return false; |
252 } | 252 } |
253 | 253 |
254 if (setenv(kSandboxDescriptorEnvironmentVarName, desc_str, 1)) { | 254 if (setenv(kSandboxDescriptorEnvironmentVarName, desc_str, 1)) { |
255 perror("setenv"); | 255 perror("setenv"); |
256 close(chroot_signal_fd); | 256 close(chroot_signal_fd); |
257 return false; | 257 return false; |
258 } | 258 } |
259 | 259 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 if (!FindProcessHoldingSocket(&pid, inode)) | 372 if (!FindProcessHoldingSocket(&pid, inode)) |
373 return 1; | 373 return 1; |
374 printf("%d\n", pid); | 374 printf("%d\n", pid); |
375 return 0; | 375 return 0; |
376 } | 376 } |
377 // Likewise, we cannot adjust /proc/pid/oom_adj for sandboxed renderers | 377 // Likewise, we cannot adjust /proc/pid/oom_adj for sandboxed renderers |
378 // because those files are owned by root. So we need another helper here. | 378 // because those files are owned by root. So we need another helper here. |
379 if (argc == 4 && (0 == strcmp(argv[1], kAdjustOOMScoreSwitch))) { | 379 if (argc == 4 && (0 == strcmp(argv[1], kAdjustOOMScoreSwitch))) { |
380 char* endptr; | 380 char* endptr; |
381 long score; | 381 long score; |
382 pid_t pid = strtoul(argv[2], &endptr, 10); | 382 unsigned long pid_ul = strtoul(argv[2], &endptr, 10); |
383 if (pid == ULONG_MAX || *endptr) | 383 if (pid_ul == ULONG_MAX || *endptr) |
384 return 1; | 384 return 1; |
| 385 pid_t pid = pid_ul; |
385 score = strtol(argv[3], &endptr, 10); | 386 score = strtol(argv[3], &endptr, 10); |
386 if (score == LONG_MAX || score == LONG_MIN || *endptr) | 387 if (score == LONG_MAX || score == LONG_MIN || *endptr) |
387 return 1; | 388 return 1; |
388 return AdjustOOMScore(pid, score); | 389 return AdjustOOMScore(pid, score); |
389 } | 390 } |
390 | 391 |
391 if (!MoveToNewPIDNamespace()) | 392 if (!MoveToNewPIDNamespace()) |
392 return 1; | 393 return 1; |
393 if (!SpawnChrootHelper()) | 394 if (!SpawnChrootHelper()) |
394 return 1; | 395 return 1; |
395 if (!DropRoot()) | 396 if (!DropRoot()) |
396 return 1; | 397 return 1; |
397 if (!SetupChildEnvironment()) | 398 if (!SetupChildEnvironment()) |
398 return 1; | 399 return 1; |
399 | 400 |
400 execv(argv[1], &argv[1]); | 401 execv(argv[1], &argv[1]); |
401 FatalError("execv failed"); | 402 FatalError("execv failed"); |
402 | 403 |
403 return 1; | 404 return 1; |
404 } | 405 } |
OLD | NEW |