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 // The following is duplicated from base/linux_utils.cc. | 5 // The following is duplicated from base/linux_utils.cc. |
6 // We shouldn't link against C++ code in a setuid binary. | 6 // We shouldn't link against C++ code in a setuid binary. |
7 | 7 |
| 8 #include "sandbox/linux/suid/linux_util.h" |
| 9 |
8 #define _GNU_SOURCE // For O_DIRECTORY | 10 #define _GNU_SOURCE // For O_DIRECTORY |
9 #include "linux_util.h" | |
10 | 11 |
11 #include <dirent.h> | 12 #include <dirent.h> |
12 #include <errno.h> | 13 #include <errno.h> |
13 #include <fcntl.h> | 14 #include <fcntl.h> |
14 #include <limits.h> | 15 #include <limits.h> |
15 #include <stdio.h> | 16 #include <stdio.h> |
16 #include <stdlib.h> | 17 #include <stdlib.h> |
17 #include <string.h> | 18 #include <string.h> |
18 #include <sys/stat.h> | 19 #include <sys/stat.h> |
19 #include <sys/types.h> | 20 #include <sys/types.h> |
20 #include <unistd.h> | 21 #include <unistd.h> |
21 | 22 |
22 // expected prefix of the target of the /proc/self/fd/%d link for a socket | 23 // expected prefix of the target of the /proc/self/fd/%d link for a socket |
23 static const char kSocketLinkPrefix[] = "socket:["; | 24 static const char kSocketLinkPrefix[] = "socket:["; |
24 | 25 |
25 // Parse a symlink in /proc/pid/fd/$x and return the inode number of the | 26 // Parse a symlink in /proc/pid/fd/$x and return the inode number of the |
26 // socket. | 27 // socket. |
27 // inode_out: (output) set to the inode number on success | 28 // inode_out: (output) set to the inode number on success |
28 // path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor) | 29 // path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor) |
29 static bool ProcPathGetInodeAt(ino_t* inode_out, int base_dir_fd, | 30 static bool ProcPathGetInodeAt(ino_t* inode_out, |
| 31 int base_dir_fd, |
30 const char* path) { | 32 const char* path) { |
31 // We also check that the path is relative. | 33 // We also check that the path is relative. |
32 if (!inode_out || !path || *path == '/') | 34 if (!inode_out || !path || *path == '/') |
33 return false; | 35 return false; |
34 char buf[256]; | 36 char buf[256]; |
35 const ssize_t n = readlinkat(base_dir_fd, path, buf, sizeof(buf) - 1); | 37 const ssize_t n = readlinkat(base_dir_fd, path, buf, sizeof(buf) - 1); |
36 if (n < 0) | 38 if (n < 0) |
37 return false; | 39 return false; |
38 buf[n] = 0; | 40 buf[n] = 0; |
39 | 41 |
40 if (memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1)) | 42 if (memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1)) |
41 return false; | 43 return false; |
42 | 44 |
43 char *endptr = NULL; | 45 char* endptr = NULL; |
44 errno = 0; | 46 errno = 0; |
45 const unsigned long long int inode_ull = | 47 const unsigned long long int inode_ull = |
46 strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10); | 48 strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10); |
47 if (inode_ull == ULLONG_MAX || !endptr || *endptr != ']' || errno != 0) | 49 if (inode_ull == ULLONG_MAX || !endptr || *endptr != ']' || errno != 0) |
48 return false; | 50 return false; |
49 | 51 |
50 *inode_out = inode_ull; | 52 *inode_out = inode_ull; |
51 return true; | 53 return true; |
52 } | 54 } |
53 | 55 |
(...skipping 11 matching lines...) Expand all Loading... |
65 bool FindProcessHoldingSocket(pid_t* pid_out, ino_t socket_inode) { | 67 bool FindProcessHoldingSocket(pid_t* pid_out, ino_t socket_inode) { |
66 bool already_found = false; | 68 bool already_found = false; |
67 | 69 |
68 DIR* proc = opendir("/proc"); | 70 DIR* proc = opendir("/proc"); |
69 if (!proc) | 71 if (!proc) |
70 return false; | 72 return false; |
71 | 73 |
72 const uid_t uid = getuid(); | 74 const uid_t uid = getuid(); |
73 struct dirent* dent; | 75 struct dirent* dent; |
74 while ((dent = readdir(proc))) { | 76 while ((dent = readdir(proc))) { |
75 char *endptr = NULL; | 77 char* endptr = NULL; |
76 errno = 0; | 78 errno = 0; |
77 const unsigned long int pid_ul = strtoul(dent->d_name, &endptr, 10); | 79 const unsigned long int pid_ul = strtoul(dent->d_name, &endptr, 10); |
78 if (pid_ul == ULONG_MAX || !endptr || *endptr || errno != 0) | 80 if (pid_ul == ULONG_MAX || !endptr || *endptr || errno != 0) |
79 continue; | 81 continue; |
80 | 82 |
81 // We have this setuid code here because the zygote and its children have | 83 // We have this setuid code here because the zygote and its children have |
82 // /proc/$pid/fd owned by root. While scanning through /proc, we add this | 84 // /proc/$pid/fd owned by root. While scanning through /proc, we add this |
83 // extra check so users cannot accidentally gain information about other | 85 // extra check so users cannot accidentally gain information about other |
84 // users' processes. To determine process ownership, we use the property | 86 // users' processes. To determine process ownership, we use the property |
85 // that if user foo owns process N, then /proc/N is owned by foo. | 87 // that if user foo owns process N, then /proc/N is owned by foo. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 128 } |
127 } | 129 } |
128 } | 130 } |
129 closedir(fd); | 131 closedir(fd); |
130 close(proc_pid_fd); | 132 close(proc_pid_fd); |
131 } | 133 } |
132 closedir(proc); | 134 closedir(proc); |
133 | 135 |
134 return already_found; | 136 return already_found; |
135 } | 137 } |
OLD | NEW |