blob: 11903a4a03337c82d50116a8fc27b4291642087a [file] [log] [blame]
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -04001/* Copyright (C) 2017 The Android Open Source Project
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "system.h"
17
18#include <errno.h>
19#include <fcntl.h>
Luis Hector Chavez71323552017-09-05 09:17:22 -070020#include <grp.h>
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040021#include <net/if.h>
Luis Hector Chavez71323552017-09-05 09:17:22 -070022#include <pwd.h>
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040023#include <stdbool.h>
24#include <stdio.h>
25#include <string.h>
26#include <sys/ioctl.h>
27#include <sys/prctl.h>
28#include <sys/socket.h>
29#include <sys/stat.h>
30#include <unistd.h>
31
32#include "util.h"
33
34#ifdef HAVE_SECUREBITS_H
35#include <linux/securebits.h>
36#else
37#define SECURE_ALL_BITS 0x55
38#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
39#endif
Jorge Lucangeli Obesa6eb21a2017-04-20 10:44:00 -040040
41#define SECURE_BITS_NO_AMBIENT 0x15
42#define SECURE_LOCKS_NO_AMBIENT (SECURE_BITS_NO_AMBIENT << 1)
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040043
44/*
45 * Assert the value of SECURE_ALL_BITS at compile-time.
Jorge Lucangeli Obesa6eb21a2017-04-20 10:44:00 -040046 * Android devices are currently compiled against 4.4 kernel headers. Kernel 4.3
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040047 * added a new securebit.
48 * When a new securebit is added, the new SECURE_ALL_BITS mask will return EPERM
49 * when used on older kernels. The compile-time assert will catch this situation
50 * at compile time.
51 */
Jorge Lucangeli Obesa6eb21a2017-04-20 10:44:00 -040052#if defined(__ANDROID__)
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040053_Static_assert(SECURE_ALL_BITS == 0x55, "SECURE_ALL_BITS == 0x55.");
54#endif
55
Luis Hector Chavezec0a2c12017-06-29 20:29:57 -070056int lock_securebits(uint64_t skip_mask)
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040057{
58 /*
Jorge Lucangeli Obesa6eb21a2017-04-20 10:44:00 -040059 * Ambient capabilities can only be raised if they're already present
60 * in the permitted *and* inheritable set. Therefore, we don't really
61 * need to lock the NO_CAP_AMBIENT_RAISE securebit, since we are already
62 * configuring the permitted and inheritable set.
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040063 */
Dylan Reida7f4fc92017-07-13 18:45:23 -070064 unsigned long securebits =
Luis Hector Chavezec0a2c12017-06-29 20:29:57 -070065 (SECURE_BITS_NO_AMBIENT | SECURE_LOCKS_NO_AMBIENT) & ~skip_mask;
66 if (!securebits) {
67 return 0;
68 }
69 int securebits_ret = prctl(PR_SET_SECUREBITS, securebits);
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -040070 if (securebits_ret < 0) {
71 pwarn("prctl(PR_SET_SECUREBITS) failed");
72 return -1;
73 }
74
75 return 0;
76}
77
78int write_proc_file(pid_t pid, const char *content, const char *basename)
79{
80 int fd, ret;
81 size_t sz, len;
82 ssize_t written;
83 char filename[32];
84
85 sz = sizeof(filename);
86 ret = snprintf(filename, sz, "/proc/%d/%s", pid, basename);
87 if (ret < 0 || (size_t)ret >= sz) {
88 warn("failed to generate %s filename", basename);
89 return -1;
90 }
91
92 fd = open(filename, O_WRONLY | O_CLOEXEC);
93 if (fd < 0) {
94 pwarn("failed to open '%s'", filename);
95 return -errno;
96 }
97
98 len = strlen(content);
99 written = write(fd, content, len);
100 if (written < 0) {
101 pwarn("failed to write '%s'", filename);
102 return -1;
103 }
104
105 if ((size_t)written < len) {
106 warn("failed to write %zu bytes to '%s'", len, filename);
107 return -1;
108 }
109 close(fd);
110 return 0;
111}
112
113/*
114 * We specifically do not use cap_valid() as that only tells us the last
115 * valid cap we were *compiled* against (i.e. what the version of kernel
116 * headers says). If we run on a different kernel version, then it's not
117 * uncommon for that to be less (if an older kernel) or more (if a newer
118 * kernel).
119 * Normally, we suck up the answer via /proc. On Android, not all processes are
120 * guaranteed to be able to access '/proc/sys/kernel/cap_last_cap' so we
121 * programmatically find the value by calling prctl(PR_CAPBSET_READ).
122 */
123unsigned int get_last_valid_cap(void)
124{
125 unsigned int last_valid_cap = 0;
126 if (is_android()) {
127 for (; prctl(PR_CAPBSET_READ, last_valid_cap, 0, 0, 0) >= 0;
128 ++last_valid_cap)
129 ;
130
131 /* |last_valid_cap| will be the first failing value. */
132 if (last_valid_cap > 0) {
133 last_valid_cap--;
134 }
135 } else {
136 const char cap_file[] = "/proc/sys/kernel/cap_last_cap";
137 FILE *fp = fopen(cap_file, "re");
138 if (fscanf(fp, "%u", &last_valid_cap) != 1)
139 pdie("fscanf(%s)", cap_file);
140 fclose(fp);
141 }
142 return last_valid_cap;
143}
144
Jorge Lucangeli Obesa6eb21a2017-04-20 10:44:00 -0400145int cap_ambient_supported(void)
146{
147 return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) >=
148 0;
149}
150
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400151int config_net_loopback(void)
152{
153 const char ifname[] = "lo";
154 int sock;
155 struct ifreq ifr;
156
157 /* Make sure people don't try to add really long names. */
158 _Static_assert(sizeof(ifname) <= IFNAMSIZ, "interface name too long");
159
160 sock = socket(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
161 if (sock < 0) {
162 pwarn("socket(AF_LOCAL) failed");
163 return -1;
164 }
165
166 /*
167 * Do the equiv of `ip link set up lo`. The kernel will assign
168 * IPv4 (127.0.0.1) & IPv6 (::1) addresses automatically!
169 */
170 strcpy(ifr.ifr_name, ifname);
171 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
172 pwarn("ioctl(SIOCGIFFLAGS) failed");
173 return -1;
174 }
175
176 /* The kernel preserves ifr.ifr_name for use. */
177 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
178 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
179 pwarn("ioctl(SIOCSIFFLAGS) failed");
180 return -1;
181 }
182
183 close(sock);
184 return 0;
185}
186
187int setup_pipe_end(int fds[2], size_t index)
188{
189 if (index > 1)
190 return -1;
191
192 close(fds[1 - index]);
193 return fds[index];
194}
195
196int setup_and_dupe_pipe_end(int fds[2], size_t index, int fd)
197{
198 if (index > 1)
199 return -1;
200
201 close(fds[1 - index]);
202 /* dup2(2) the corresponding end of the pipe into |fd|. */
203 return dup2(fds[index], fd);
204}
205
206int write_pid_to_path(pid_t pid, const char *path)
207{
Mike Frysinger0b5cffa2017-08-15 18:06:18 -0400208 FILE *fp = fopen(path, "we");
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400209
210 if (!fp) {
211 pwarn("failed to open '%s'", path);
212 return -errno;
213 }
214 if (fprintf(fp, "%d\n", (int)pid) < 0) {
215 /* fprintf(3) does not set errno on failure. */
216 warn("fprintf(%s) failed", path);
217 return -1;
218 }
219 if (fclose(fp)) {
220 pwarn("fclose(%s) failed", path);
221 return -errno;
222 }
223
224 return 0;
225}
226
227/*
228 * setup_mount_destination: Ensures the mount target exists.
229 * Creates it if needed and possible.
230 */
231int setup_mount_destination(const char *source, const char *dest, uid_t uid,
Mike Frysingereaab4202017-08-14 14:57:21 -0400232 uid_t gid, bool bind)
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400233{
234 int rc;
235 struct stat st_buf;
Mike Frysingereaab4202017-08-14 14:57:21 -0400236 bool domkdir;
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400237
238 rc = stat(dest, &st_buf);
239 if (rc == 0) /* destination exists */
240 return 0;
241
242 /*
243 * Try to create the destination.
244 * Either make a directory or touch a file depending on the source type.
Mike Frysingereaab4202017-08-14 14:57:21 -0400245 *
246 * If the source isn't an absolute path, assume it is a filesystem type
247 * such as "tmpfs" and create a directory to mount it on. The dest will
248 * be something like "none" or "proc" which we shouldn't be checking.
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400249 */
Mike Frysingereaab4202017-08-14 14:57:21 -0400250 if (source[0] == '/') {
251 /* The source is an absolute path -- it better exist! */
252 rc = stat(source, &st_buf);
253 if (rc)
254 return -errno;
255
256 /*
257 * If bind mounting, we only create a directory if the source
258 * is a directory, else we always bind mount it as a file to
259 * support device nodes, sockets, etc...
260 *
261 * For all other mounts, we assume a block/char source is
262 * going to want a directory to mount to. If the source is
263 * something else (e.g. a fifo or socket), this probably will
264 * not do the right thing, but we'll fail later on when we try
265 * to mount(), so shouldn't be a big deal.
266 */
267 domkdir = S_ISDIR(st_buf.st_mode) ||
268 (!bind && (S_ISBLK(st_buf.st_mode) ||
269 S_ISCHR(st_buf.st_mode)));
270 } else {
271 /* The source is a relative path -- assume it's a pseudo fs. */
272
273 /* Disallow relative bind mounts. */
274 if (bind)
275 return -EINVAL;
276
277 domkdir = true;
278 }
279
280 /* Now that we know what we want to do, do it! */
281 if (domkdir) {
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400282 if (mkdir(dest, 0700))
283 return -errno;
284 } else {
Mike Frysingereaab4202017-08-14 14:57:21 -0400285 int fd = open(dest, O_RDWR | O_CREAT | O_CLOEXEC, 0700);
Jorge Lucangeli Obes0b208772017-04-19 14:15:46 -0400286 if (fd < 0)
287 return -errno;
288 close(fd);
289 }
290 return chown(dest, uid, gid);
291}
Luis Hector Chavez71323552017-09-05 09:17:22 -0700292
293/*
294 * lookup_user: Gets the uid/gid for the given username.
295 */
296int lookup_user(const char *user, uid_t *uid, gid_t *gid)
297{
298 char *buf = NULL;
299 struct passwd pw;
300 struct passwd *ppw = NULL;
301 ssize_t sz = sysconf(_SC_GETPW_R_SIZE_MAX);
302 if (sz == -1)
303 sz = 65536; /* your guess is as good as mine... */
304
305 /*
306 * sysconf(_SC_GETPW_R_SIZE_MAX), under glibc, is documented to return
307 * the maximum needed size of the buffer, so we don't have to search.
308 */
309 buf = malloc(sz);
310 if (!buf)
311 return -ENOMEM;
312 getpwnam_r(user, &pw, buf, sz, &ppw);
313 /*
314 * We're safe to free the buffer here. The strings inside |pw| point
315 * inside |buf|, but we don't use any of them; this leaves the pointers
316 * dangling but it's safe. |ppw| points at |pw| if getpwnam_r(3)
317 * succeeded.
318 */
319 free(buf);
320 /* getpwnam_r(3) does *not* set errno when |ppw| is NULL. */
321 if (!ppw)
322 return -1;
323
324 *uid = ppw->pw_uid;
325 *gid = ppw->pw_gid;
326 return 0;
327}
328
329/*
330 * lookup_group: Gets the gid for the given group name.
331 */
332int lookup_group(const char *group, gid_t *gid)
333{
334 char *buf = NULL;
335 struct group gr;
336 struct group *pgr = NULL;
337 ssize_t sz = sysconf(_SC_GETGR_R_SIZE_MAX);
338 if (sz == -1)
339 sz = 65536; /* and mine is as good as yours, really */
340
341 /*
342 * sysconf(_SC_GETGR_R_SIZE_MAX), under glibc, is documented to return
343 * the maximum needed size of the buffer, so we don't have to search.
344 */
345 buf = malloc(sz);
346 if (!buf)
347 return -ENOMEM;
348 getgrnam_r(group, &gr, buf, sz, &pgr);
349 /*
350 * We're safe to free the buffer here. The strings inside gr point
351 * inside buf, but we don't use any of them; this leaves the pointers
352 * dangling but it's safe. pgr points at gr if getgrnam_r succeeded.
353 */
354 free(buf);
355 /* getgrnam_r(3) does *not* set errno when |pgr| is NULL. */
356 if (!pgr)
357 return -1;
358
359 *gid = pgr->gr_gid;
360 return 0;
361}