1*4b9c6d91SCole Faust /* Copyright 2017 The ChromiumOS Authors
2*4b9c6d91SCole Faust * Use of this source code is governed by a BSD-style license that can be
3*4b9c6d91SCole Faust * found in the LICENSE file.
4*4b9c6d91SCole Faust */
5*4b9c6d91SCole Faust
6*4b9c6d91SCole Faust #include "system.h"
7*4b9c6d91SCole Faust
8*4b9c6d91SCole Faust #include <errno.h>
9*4b9c6d91SCole Faust #include <fcntl.h>
10*4b9c6d91SCole Faust #include <grp.h>
11*4b9c6d91SCole Faust #include <net/if.h>
12*4b9c6d91SCole Faust #include <pwd.h>
13*4b9c6d91SCole Faust #include <stdbool.h>
14*4b9c6d91SCole Faust #include <stdio.h>
15*4b9c6d91SCole Faust #include <string.h>
16*4b9c6d91SCole Faust #include <sys/ioctl.h>
17*4b9c6d91SCole Faust #include <sys/prctl.h>
18*4b9c6d91SCole Faust #include <sys/socket.h>
19*4b9c6d91SCole Faust #include <sys/stat.h>
20*4b9c6d91SCole Faust #include <sys/statvfs.h>
21*4b9c6d91SCole Faust #include <unistd.h>
22*4b9c6d91SCole Faust
23*4b9c6d91SCole Faust #include <linux/securebits.h>
24*4b9c6d91SCole Faust
25*4b9c6d91SCole Faust #include "syscall_wrapper.h"
26*4b9c6d91SCole Faust #include "util.h"
27*4b9c6d91SCole Faust
28*4b9c6d91SCole Faust /*
29*4b9c6d91SCole Faust * SECBIT_NO_CAP_AMBIENT_RAISE was added in kernel 4.3, so fill in the
30*4b9c6d91SCole Faust * definition if the securebits header doesn't provide it.
31*4b9c6d91SCole Faust */
32*4b9c6d91SCole Faust #ifndef SECBIT_NO_CAP_AMBIENT_RAISE
33*4b9c6d91SCole Faust #define SECBIT_NO_CAP_AMBIENT_RAISE (issecure_mask(6))
34*4b9c6d91SCole Faust #endif
35*4b9c6d91SCole Faust
36*4b9c6d91SCole Faust #ifndef SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED
37*4b9c6d91SCole Faust #define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED (issecure_mask(7))
38*4b9c6d91SCole Faust #endif
39*4b9c6d91SCole Faust
40*4b9c6d91SCole Faust /*
41*4b9c6d91SCole Faust * Assert the value of SECURE_ALL_BITS at compile-time.
42*4b9c6d91SCole Faust * Android devices are currently compiled against 4.4 kernel headers. Kernel 4.3
43*4b9c6d91SCole Faust * added a new securebit.
44*4b9c6d91SCole Faust * When a new securebit is added, the new SECURE_ALL_BITS mask will return EPERM
45*4b9c6d91SCole Faust * when used on older kernels. The compile-time assert will catch this situation
46*4b9c6d91SCole Faust * at compile time.
47*4b9c6d91SCole Faust */
48*4b9c6d91SCole Faust #if defined(__ANDROID__)
49*4b9c6d91SCole Faust _Static_assert(SECURE_ALL_BITS == 0x55, "SECURE_ALL_BITS == 0x55.");
50*4b9c6d91SCole Faust #endif
51*4b9c6d91SCole Faust
52*4b9c6d91SCole Faust /* Used by lookup_(user|group) functions. */
53*4b9c6d91SCole Faust #define MAX_PWENT_SZ (1 << 20)
54*4b9c6d91SCole Faust #define MAX_GRENT_SZ (1 << 20)
55*4b9c6d91SCole Faust
secure_noroot_set_and_locked(uint64_t mask)56*4b9c6d91SCole Faust int secure_noroot_set_and_locked(uint64_t mask)
57*4b9c6d91SCole Faust {
58*4b9c6d91SCole Faust return (mask & (SECBIT_NOROOT | SECBIT_NOROOT_LOCKED)) ==
59*4b9c6d91SCole Faust (SECBIT_NOROOT | SECBIT_NOROOT_LOCKED);
60*4b9c6d91SCole Faust }
61*4b9c6d91SCole Faust
lock_securebits(uint64_t skip_mask,bool require_keep_caps)62*4b9c6d91SCole Faust int lock_securebits(uint64_t skip_mask, bool require_keep_caps)
63*4b9c6d91SCole Faust {
64*4b9c6d91SCole Faust /* The general idea is to set all bits, subject to exceptions below. */
65*4b9c6d91SCole Faust unsigned long securebits = SECURE_ALL_BITS | SECURE_ALL_LOCKS;
66*4b9c6d91SCole Faust
67*4b9c6d91SCole Faust /*
68*4b9c6d91SCole Faust * SECBIT_KEEP_CAPS is special in that it is automatically cleared on
69*4b9c6d91SCole Faust * execve(2). This implies that attempts to set SECBIT_KEEP_CAPS (as is
70*4b9c6d91SCole Faust * the default) in processes that have it locked already (such as nested
71*4b9c6d91SCole Faust * minijail usage) would fail. Thus, unless the caller requires it,
72*4b9c6d91SCole Faust * allow it to remain off if it is already locked.
73*4b9c6d91SCole Faust */
74*4b9c6d91SCole Faust if (!require_keep_caps) {
75*4b9c6d91SCole Faust int current_securebits = prctl(PR_GET_SECUREBITS);
76*4b9c6d91SCole Faust if (current_securebits < 0) {
77*4b9c6d91SCole Faust pwarn("prctl(PR_GET_SECUREBITS) failed");
78*4b9c6d91SCole Faust return -1;
79*4b9c6d91SCole Faust }
80*4b9c6d91SCole Faust
81*4b9c6d91SCole Faust if ((current_securebits & SECBIT_KEEP_CAPS_LOCKED) != 0 &&
82*4b9c6d91SCole Faust (current_securebits & SECBIT_KEEP_CAPS) == 0) {
83*4b9c6d91SCole Faust securebits &= ~SECBIT_KEEP_CAPS;
84*4b9c6d91SCole Faust }
85*4b9c6d91SCole Faust }
86*4b9c6d91SCole Faust
87*4b9c6d91SCole Faust /*
88*4b9c6d91SCole Faust * Ambient capabilities can only be raised if they're already present
89*4b9c6d91SCole Faust * in the permitted *and* inheritable set. Therefore, we don't really
90*4b9c6d91SCole Faust * need to lock the NO_CAP_AMBIENT_RAISE securebit, since we are already
91*4b9c6d91SCole Faust * configuring the permitted and inheritable set.
92*4b9c6d91SCole Faust */
93*4b9c6d91SCole Faust securebits &=
94*4b9c6d91SCole Faust ~(SECBIT_NO_CAP_AMBIENT_RAISE | SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED);
95*4b9c6d91SCole Faust
96*4b9c6d91SCole Faust /* Don't set any bits that the user requested not to be touched. */
97*4b9c6d91SCole Faust securebits &= ~skip_mask;
98*4b9c6d91SCole Faust
99*4b9c6d91SCole Faust if (!securebits) {
100*4b9c6d91SCole Faust warn("not locking any securebits");
101*4b9c6d91SCole Faust return 0;
102*4b9c6d91SCole Faust }
103*4b9c6d91SCole Faust int securebits_ret = prctl(PR_SET_SECUREBITS, securebits);
104*4b9c6d91SCole Faust if (securebits_ret < 0) {
105*4b9c6d91SCole Faust pwarn("prctl(PR_SET_SECUREBITS) failed");
106*4b9c6d91SCole Faust return -1;
107*4b9c6d91SCole Faust }
108*4b9c6d91SCole Faust
109*4b9c6d91SCole Faust return 0;
110*4b9c6d91SCole Faust }
111*4b9c6d91SCole Faust
write_proc_file(pid_t pid,const char * content,const char * basename)112*4b9c6d91SCole Faust int write_proc_file(pid_t pid, const char *content, const char *basename)
113*4b9c6d91SCole Faust {
114*4b9c6d91SCole Faust attribute_cleanup_fd int fd = -1;
115*4b9c6d91SCole Faust int ret;
116*4b9c6d91SCole Faust size_t sz, len;
117*4b9c6d91SCole Faust ssize_t written;
118*4b9c6d91SCole Faust char filename[32];
119*4b9c6d91SCole Faust
120*4b9c6d91SCole Faust sz = sizeof(filename);
121*4b9c6d91SCole Faust ret = snprintf(filename, sz, "/proc/%d/%s", pid, basename);
122*4b9c6d91SCole Faust if (ret < 0 || (size_t)ret >= sz) {
123*4b9c6d91SCole Faust warn("failed to generate %s filename", basename);
124*4b9c6d91SCole Faust return -1;
125*4b9c6d91SCole Faust }
126*4b9c6d91SCole Faust
127*4b9c6d91SCole Faust fd = open(filename, O_WRONLY | O_CLOEXEC);
128*4b9c6d91SCole Faust if (fd < 0) {
129*4b9c6d91SCole Faust pwarn("failed to open '%s'", filename);
130*4b9c6d91SCole Faust return -errno;
131*4b9c6d91SCole Faust }
132*4b9c6d91SCole Faust
133*4b9c6d91SCole Faust len = strlen(content);
134*4b9c6d91SCole Faust written = write(fd, content, len);
135*4b9c6d91SCole Faust if (written < 0) {
136*4b9c6d91SCole Faust pwarn("failed to write '%s'", filename);
137*4b9c6d91SCole Faust return -errno;
138*4b9c6d91SCole Faust }
139*4b9c6d91SCole Faust
140*4b9c6d91SCole Faust if ((size_t)written < len) {
141*4b9c6d91SCole Faust warn("failed to write %zu bytes to '%s'", len, filename);
142*4b9c6d91SCole Faust return -1;
143*4b9c6d91SCole Faust }
144*4b9c6d91SCole Faust return 0;
145*4b9c6d91SCole Faust }
146*4b9c6d91SCole Faust
147*4b9c6d91SCole Faust /*
148*4b9c6d91SCole Faust * We specifically do not use cap_valid() as that only tells us the last
149*4b9c6d91SCole Faust * valid cap we were *compiled* against (i.e. what the version of kernel
150*4b9c6d91SCole Faust * headers says). If we run on a different kernel version, then it's not
151*4b9c6d91SCole Faust * uncommon for that to be less (if an older kernel) or more (if a newer
152*4b9c6d91SCole Faust * kernel).
153*4b9c6d91SCole Faust * Normally, we suck up the answer via /proc. On Android, not all processes are
154*4b9c6d91SCole Faust * guaranteed to be able to access '/proc/sys/kernel/cap_last_cap' so we
155*4b9c6d91SCole Faust * programmatically find the value by calling prctl(PR_CAPBSET_READ).
156*4b9c6d91SCole Faust */
get_last_valid_cap(void)157*4b9c6d91SCole Faust unsigned int get_last_valid_cap(void)
158*4b9c6d91SCole Faust {
159*4b9c6d91SCole Faust unsigned int last_valid_cap = 0;
160*4b9c6d91SCole Faust if (is_android()) {
161*4b9c6d91SCole Faust for (; prctl(PR_CAPBSET_READ, last_valid_cap, 0, 0, 0) >= 0;
162*4b9c6d91SCole Faust ++last_valid_cap)
163*4b9c6d91SCole Faust ;
164*4b9c6d91SCole Faust
165*4b9c6d91SCole Faust /* |last_valid_cap| will be the first failing value. */
166*4b9c6d91SCole Faust if (last_valid_cap > 0) {
167*4b9c6d91SCole Faust last_valid_cap--;
168*4b9c6d91SCole Faust }
169*4b9c6d91SCole Faust } else {
170*4b9c6d91SCole Faust static const char cap_file[] = "/proc/sys/kernel/cap_last_cap";
171*4b9c6d91SCole Faust FILE *fp = fopen(cap_file, "re");
172*4b9c6d91SCole Faust if (!fp)
173*4b9c6d91SCole Faust pdie("fopen(%s)", cap_file);
174*4b9c6d91SCole Faust if (fscanf(fp, "%u", &last_valid_cap) != 1)
175*4b9c6d91SCole Faust pdie("fscanf(%s)", cap_file);
176*4b9c6d91SCole Faust fclose(fp);
177*4b9c6d91SCole Faust }
178*4b9c6d91SCole Faust return last_valid_cap;
179*4b9c6d91SCole Faust }
180*4b9c6d91SCole Faust
cap_ambient_supported(void)181*4b9c6d91SCole Faust int cap_ambient_supported(void)
182*4b9c6d91SCole Faust {
183*4b9c6d91SCole Faust return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) >=
184*4b9c6d91SCole Faust 0;
185*4b9c6d91SCole Faust }
186*4b9c6d91SCole Faust
config_net_loopback(void)187*4b9c6d91SCole Faust int config_net_loopback(void)
188*4b9c6d91SCole Faust {
189*4b9c6d91SCole Faust const char ifname[] = "lo";
190*4b9c6d91SCole Faust attribute_cleanup_fd int sock = -1;
191*4b9c6d91SCole Faust struct ifreq ifr;
192*4b9c6d91SCole Faust
193*4b9c6d91SCole Faust /* Make sure people don't try to add really long names. */
194*4b9c6d91SCole Faust _Static_assert(sizeof(ifname) <= IFNAMSIZ, "interface name too long");
195*4b9c6d91SCole Faust
196*4b9c6d91SCole Faust sock = socket(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
197*4b9c6d91SCole Faust if (sock < 0) {
198*4b9c6d91SCole Faust pwarn("socket(AF_LOCAL) failed");
199*4b9c6d91SCole Faust return -1;
200*4b9c6d91SCole Faust }
201*4b9c6d91SCole Faust
202*4b9c6d91SCole Faust /*
203*4b9c6d91SCole Faust * Do the equiv of `ip link set up lo`. The kernel will assign
204*4b9c6d91SCole Faust * IPv4 (127.0.0.1) & IPv6 (::1) addresses automatically!
205*4b9c6d91SCole Faust */
206*4b9c6d91SCole Faust strcpy(ifr.ifr_name, ifname);
207*4b9c6d91SCole Faust if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
208*4b9c6d91SCole Faust pwarn("ioctl(SIOCGIFFLAGS) failed");
209*4b9c6d91SCole Faust return -1;
210*4b9c6d91SCole Faust }
211*4b9c6d91SCole Faust
212*4b9c6d91SCole Faust /* The kernel preserves ifr.ifr_name for use. */
213*4b9c6d91SCole Faust ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
214*4b9c6d91SCole Faust if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
215*4b9c6d91SCole Faust pwarn("ioctl(SIOCSIFFLAGS) failed");
216*4b9c6d91SCole Faust return -1;
217*4b9c6d91SCole Faust }
218*4b9c6d91SCole Faust
219*4b9c6d91SCole Faust return 0;
220*4b9c6d91SCole Faust }
221*4b9c6d91SCole Faust
write_pid_to_path(pid_t pid,const char * path)222*4b9c6d91SCole Faust int write_pid_to_path(pid_t pid, const char *path)
223*4b9c6d91SCole Faust {
224*4b9c6d91SCole Faust FILE *fp = fopen(path, "we");
225*4b9c6d91SCole Faust
226*4b9c6d91SCole Faust if (!fp) {
227*4b9c6d91SCole Faust pwarn("failed to open '%s'", path);
228*4b9c6d91SCole Faust return -errno;
229*4b9c6d91SCole Faust }
230*4b9c6d91SCole Faust if (fprintf(fp, "%d\n", (int)pid) < 0) {
231*4b9c6d91SCole Faust /* fprintf(3) does not set errno on failure. */
232*4b9c6d91SCole Faust warn("fprintf(%s) failed", path);
233*4b9c6d91SCole Faust fclose(fp);
234*4b9c6d91SCole Faust return -1;
235*4b9c6d91SCole Faust }
236*4b9c6d91SCole Faust if (fclose(fp)) {
237*4b9c6d91SCole Faust pwarn("fclose(%s) failed", path);
238*4b9c6d91SCole Faust return -errno;
239*4b9c6d91SCole Faust }
240*4b9c6d91SCole Faust
241*4b9c6d91SCole Faust return 0;
242*4b9c6d91SCole Faust }
243*4b9c6d91SCole Faust
244*4b9c6d91SCole Faust /*
245*4b9c6d91SCole Faust * Create the |path| directory and its parents (if need be) with |mode|.
246*4b9c6d91SCole Faust * If not |isdir|, then |path| is actually a file, so the last component
247*4b9c6d91SCole Faust * will not be created.
248*4b9c6d91SCole Faust */
mkdir_p(const char * path,mode_t mode,bool isdir)249*4b9c6d91SCole Faust int mkdir_p(const char *path, mode_t mode, bool isdir)
250*4b9c6d91SCole Faust {
251*4b9c6d91SCole Faust int rc;
252*4b9c6d91SCole Faust char *dir = strdup(path);
253*4b9c6d91SCole Faust if (!dir) {
254*4b9c6d91SCole Faust rc = errno;
255*4b9c6d91SCole Faust pwarn("strdup(%s) failed", path);
256*4b9c6d91SCole Faust return -rc;
257*4b9c6d91SCole Faust }
258*4b9c6d91SCole Faust
259*4b9c6d91SCole Faust /* Starting from the root, work our way out to the end. */
260*4b9c6d91SCole Faust char *p = strchr(dir + 1, '/');
261*4b9c6d91SCole Faust while (p) {
262*4b9c6d91SCole Faust *p = '\0';
263*4b9c6d91SCole Faust if (mkdir(dir, mode) && errno != EEXIST) {
264*4b9c6d91SCole Faust rc = errno;
265*4b9c6d91SCole Faust pwarn("mkdir(%s, 0%o) failed", dir, mode);
266*4b9c6d91SCole Faust free(dir);
267*4b9c6d91SCole Faust return -rc;
268*4b9c6d91SCole Faust }
269*4b9c6d91SCole Faust *p = '/';
270*4b9c6d91SCole Faust p = strchr(p + 1, '/');
271*4b9c6d91SCole Faust }
272*4b9c6d91SCole Faust
273*4b9c6d91SCole Faust /*
274*4b9c6d91SCole Faust * Create the last directory. We still check EEXIST here in case
275*4b9c6d91SCole Faust * of trailing slashes.
276*4b9c6d91SCole Faust */
277*4b9c6d91SCole Faust free(dir);
278*4b9c6d91SCole Faust if (isdir && mkdir(path, mode) && errno != EEXIST) {
279*4b9c6d91SCole Faust rc = errno;
280*4b9c6d91SCole Faust pwarn("mkdir(%s, 0%o) failed", path, mode);
281*4b9c6d91SCole Faust return -rc;
282*4b9c6d91SCole Faust }
283*4b9c6d91SCole Faust return 0;
284*4b9c6d91SCole Faust }
285*4b9c6d91SCole Faust
286*4b9c6d91SCole Faust /*
287*4b9c6d91SCole Faust * get_mount_flags: Obtain the mount flags of the mount where |source| lives.
288*4b9c6d91SCole Faust */
get_mount_flags(const char * source,unsigned long * mnt_flags)289*4b9c6d91SCole Faust int get_mount_flags(const char *source, unsigned long *mnt_flags)
290*4b9c6d91SCole Faust {
291*4b9c6d91SCole Faust if (mnt_flags) {
292*4b9c6d91SCole Faust struct statvfs stvfs_buf;
293*4b9c6d91SCole Faust int rc = statvfs(source, &stvfs_buf);
294*4b9c6d91SCole Faust if (rc) {
295*4b9c6d91SCole Faust rc = errno;
296*4b9c6d91SCole Faust pwarn("failed to look up mount flags: source=%s",
297*4b9c6d91SCole Faust source);
298*4b9c6d91SCole Faust return -rc;
299*4b9c6d91SCole Faust }
300*4b9c6d91SCole Faust *mnt_flags = stvfs_buf.f_flag;
301*4b9c6d91SCole Faust }
302*4b9c6d91SCole Faust return 0;
303*4b9c6d91SCole Faust }
304*4b9c6d91SCole Faust
305*4b9c6d91SCole Faust /*
306*4b9c6d91SCole Faust * setup_mount_destination: Ensures the mount target exists.
307*4b9c6d91SCole Faust * Creates it if needed and possible.
308*4b9c6d91SCole Faust */
setup_mount_destination(const char * source,const char * dest,uid_t uid,uid_t gid,bool bind)309*4b9c6d91SCole Faust int setup_mount_destination(const char *source, const char *dest, uid_t uid,
310*4b9c6d91SCole Faust uid_t gid, bool bind)
311*4b9c6d91SCole Faust {
312*4b9c6d91SCole Faust int rc;
313*4b9c6d91SCole Faust struct stat st_buf;
314*4b9c6d91SCole Faust bool domkdir;
315*4b9c6d91SCole Faust
316*4b9c6d91SCole Faust rc = stat(dest, &st_buf);
317*4b9c6d91SCole Faust if (rc == 0) /* destination exists */
318*4b9c6d91SCole Faust return 0;
319*4b9c6d91SCole Faust
320*4b9c6d91SCole Faust /*
321*4b9c6d91SCole Faust * Try to create the destination.
322*4b9c6d91SCole Faust * Either make a directory or touch a file depending on the source type.
323*4b9c6d91SCole Faust *
324*4b9c6d91SCole Faust * If the source isn't an absolute path, assume it is a filesystem type
325*4b9c6d91SCole Faust * such as "tmpfs" and create a directory to mount it on. The dest will
326*4b9c6d91SCole Faust * be something like "none" or "proc" which we shouldn't be checking.
327*4b9c6d91SCole Faust */
328*4b9c6d91SCole Faust if (source[0] == '/') {
329*4b9c6d91SCole Faust /* The source is an absolute path -- it better exist! */
330*4b9c6d91SCole Faust rc = stat(source, &st_buf);
331*4b9c6d91SCole Faust if (rc) {
332*4b9c6d91SCole Faust rc = errno;
333*4b9c6d91SCole Faust pwarn("stat(%s) failed", source);
334*4b9c6d91SCole Faust return -rc;
335*4b9c6d91SCole Faust }
336*4b9c6d91SCole Faust
337*4b9c6d91SCole Faust /*
338*4b9c6d91SCole Faust * If bind mounting, we only create a directory if the source
339*4b9c6d91SCole Faust * is a directory, else we always bind mount it as a file to
340*4b9c6d91SCole Faust * support device nodes, sockets, etc...
341*4b9c6d91SCole Faust *
342*4b9c6d91SCole Faust * For all other mounts, we assume a block/char source is
343*4b9c6d91SCole Faust * going to want a directory to mount to. If the source is
344*4b9c6d91SCole Faust * something else (e.g. a fifo or socket), this probably will
345*4b9c6d91SCole Faust * not do the right thing, but we'll fail later on when we try
346*4b9c6d91SCole Faust * to mount(), so shouldn't be a big deal.
347*4b9c6d91SCole Faust */
348*4b9c6d91SCole Faust domkdir = S_ISDIR(st_buf.st_mode) ||
349*4b9c6d91SCole Faust (!bind && (S_ISBLK(st_buf.st_mode) ||
350*4b9c6d91SCole Faust S_ISCHR(st_buf.st_mode)));
351*4b9c6d91SCole Faust } else {
352*4b9c6d91SCole Faust /* The source is a relative path -- assume it's a pseudo fs. */
353*4b9c6d91SCole Faust
354*4b9c6d91SCole Faust /* Disallow relative bind mounts. */
355*4b9c6d91SCole Faust if (bind) {
356*4b9c6d91SCole Faust warn("relative bind-mounts are not allowed: source=%s",
357*4b9c6d91SCole Faust source);
358*4b9c6d91SCole Faust return -EINVAL;
359*4b9c6d91SCole Faust }
360*4b9c6d91SCole Faust
361*4b9c6d91SCole Faust domkdir = true;
362*4b9c6d91SCole Faust }
363*4b9c6d91SCole Faust
364*4b9c6d91SCole Faust /*
365*4b9c6d91SCole Faust * Now that we know what we want to do, do it!
366*4b9c6d91SCole Faust * We always create the intermediate dirs and the final path with 0755
367*4b9c6d91SCole Faust * perms and root/root ownership. This shouldn't be a problem because
368*4b9c6d91SCole Faust * the actual mount will set those perms/ownership on the mount point
369*4b9c6d91SCole Faust * which is all people should need to access it.
370*4b9c6d91SCole Faust */
371*4b9c6d91SCole Faust rc = mkdir_p(dest, 0755, domkdir);
372*4b9c6d91SCole Faust if (rc)
373*4b9c6d91SCole Faust return rc;
374*4b9c6d91SCole Faust if (!domkdir) {
375*4b9c6d91SCole Faust attribute_cleanup_fd int fd =
376*4b9c6d91SCole Faust open(dest, O_RDWR | O_CREAT | O_CLOEXEC, 0700);
377*4b9c6d91SCole Faust if (fd < 0) {
378*4b9c6d91SCole Faust rc = errno;
379*4b9c6d91SCole Faust pwarn("open(%s) failed", dest);
380*4b9c6d91SCole Faust return -rc;
381*4b9c6d91SCole Faust }
382*4b9c6d91SCole Faust }
383*4b9c6d91SCole Faust if (chown(dest, uid, gid)) {
384*4b9c6d91SCole Faust rc = errno;
385*4b9c6d91SCole Faust pwarn("chown(%s, %u, %u) failed", dest, uid, gid);
386*4b9c6d91SCole Faust return -rc;
387*4b9c6d91SCole Faust }
388*4b9c6d91SCole Faust return 0;
389*4b9c6d91SCole Faust }
390*4b9c6d91SCole Faust
391*4b9c6d91SCole Faust /*
392*4b9c6d91SCole Faust * lookup_user: Gets the uid/gid for the given username.
393*4b9c6d91SCole Faust */
lookup_user(const char * user,uid_t * uid,gid_t * gid)394*4b9c6d91SCole Faust int lookup_user(const char *user, uid_t *uid, gid_t *gid)
395*4b9c6d91SCole Faust {
396*4b9c6d91SCole Faust char *buf = NULL;
397*4b9c6d91SCole Faust struct passwd pw;
398*4b9c6d91SCole Faust struct passwd *ppw = NULL;
399*4b9c6d91SCole Faust /*
400*4b9c6d91SCole Faust * sysconf(_SC_GETPW_R_SIZE_MAX), under glibc, is documented to return
401*4b9c6d91SCole Faust * a suggested starting size for the buffer, so let's try getting this
402*4b9c6d91SCole Faust * size first, and fallback to a default othersise.
403*4b9c6d91SCole Faust */
404*4b9c6d91SCole Faust ssize_t sz = sysconf(_SC_GETPW_R_SIZE_MAX);
405*4b9c6d91SCole Faust if (sz == -1)
406*4b9c6d91SCole Faust sz = 65536; /* your guess is as good as mine... */
407*4b9c6d91SCole Faust
408*4b9c6d91SCole Faust do {
409*4b9c6d91SCole Faust buf = malloc(sz);
410*4b9c6d91SCole Faust if (!buf)
411*4b9c6d91SCole Faust return -ENOMEM;
412*4b9c6d91SCole Faust int err = getpwnam_r(user, &pw, buf, sz, &ppw);
413*4b9c6d91SCole Faust /*
414*4b9c6d91SCole Faust * We're safe to free the buffer here. The strings inside |pw|
415*4b9c6d91SCole Faust * point inside |buf|, but we don't use any of them; this leaves
416*4b9c6d91SCole Faust * the pointers dangling but it's safe.
417*4b9c6d91SCole Faust * |ppw| points at |pw| if getpwnam_r(3) succeeded.
418*4b9c6d91SCole Faust */
419*4b9c6d91SCole Faust free(buf);
420*4b9c6d91SCole Faust if (err == ERANGE) {
421*4b9c6d91SCole Faust /* |buf| was too small, retry with a bigger one. */
422*4b9c6d91SCole Faust sz <<= 1;
423*4b9c6d91SCole Faust } else if (err != 0) {
424*4b9c6d91SCole Faust /* We got an error not related to the size of |buf|. */
425*4b9c6d91SCole Faust return -err;
426*4b9c6d91SCole Faust } else if (!ppw) {
427*4b9c6d91SCole Faust /* Not found. */
428*4b9c6d91SCole Faust return -ENOENT;
429*4b9c6d91SCole Faust } else {
430*4b9c6d91SCole Faust *uid = ppw->pw_uid;
431*4b9c6d91SCole Faust *gid = ppw->pw_gid;
432*4b9c6d91SCole Faust return 0;
433*4b9c6d91SCole Faust }
434*4b9c6d91SCole Faust } while (sz <= MAX_PWENT_SZ);
435*4b9c6d91SCole Faust
436*4b9c6d91SCole Faust /* A buffer of size MAX_PWENT_SZ is still too small, return an error. */
437*4b9c6d91SCole Faust return -ERANGE;
438*4b9c6d91SCole Faust }
439*4b9c6d91SCole Faust
440*4b9c6d91SCole Faust /*
441*4b9c6d91SCole Faust * lookup_group: Gets the gid for the given group name.
442*4b9c6d91SCole Faust */
lookup_group(const char * group,gid_t * gid)443*4b9c6d91SCole Faust int lookup_group(const char *group, gid_t *gid)
444*4b9c6d91SCole Faust {
445*4b9c6d91SCole Faust char *buf = NULL;
446*4b9c6d91SCole Faust struct group gr;
447*4b9c6d91SCole Faust struct group *pgr = NULL;
448*4b9c6d91SCole Faust /*
449*4b9c6d91SCole Faust * sysconf(_SC_GETGR_R_SIZE_MAX), under glibc, is documented to return
450*4b9c6d91SCole Faust * a suggested starting size for the buffer, so let's try getting this
451*4b9c6d91SCole Faust * size first, and fallback to a default otherwise.
452*4b9c6d91SCole Faust */
453*4b9c6d91SCole Faust ssize_t sz = sysconf(_SC_GETGR_R_SIZE_MAX);
454*4b9c6d91SCole Faust if (sz == -1)
455*4b9c6d91SCole Faust sz = 65536; /* and mine is as good as yours, really */
456*4b9c6d91SCole Faust
457*4b9c6d91SCole Faust do {
458*4b9c6d91SCole Faust buf = malloc(sz);
459*4b9c6d91SCole Faust if (!buf)
460*4b9c6d91SCole Faust return -ENOMEM;
461*4b9c6d91SCole Faust int err = getgrnam_r(group, &gr, buf, sz, &pgr);
462*4b9c6d91SCole Faust /*
463*4b9c6d91SCole Faust * We're safe to free the buffer here. The strings inside |gr|
464*4b9c6d91SCole Faust * point inside |buf|, but we don't use any of them; this leaves
465*4b9c6d91SCole Faust * the pointers dangling but it's safe.
466*4b9c6d91SCole Faust * |pgr| points at |gr| if getgrnam_r(3) succeeded.
467*4b9c6d91SCole Faust */
468*4b9c6d91SCole Faust free(buf);
469*4b9c6d91SCole Faust if (err == ERANGE) {
470*4b9c6d91SCole Faust /* |buf| was too small, retry with a bigger one. */
471*4b9c6d91SCole Faust sz <<= 1;
472*4b9c6d91SCole Faust } else if (err != 0) {
473*4b9c6d91SCole Faust /* We got an error not related to the size of |buf|. */
474*4b9c6d91SCole Faust return -err;
475*4b9c6d91SCole Faust } else if (!pgr) {
476*4b9c6d91SCole Faust /* Not found. */
477*4b9c6d91SCole Faust return -ENOENT;
478*4b9c6d91SCole Faust } else {
479*4b9c6d91SCole Faust *gid = pgr->gr_gid;
480*4b9c6d91SCole Faust return 0;
481*4b9c6d91SCole Faust }
482*4b9c6d91SCole Faust } while (sz <= MAX_GRENT_SZ);
483*4b9c6d91SCole Faust
484*4b9c6d91SCole Faust /* A buffer of size MAX_GRENT_SZ is still too small, return an error. */
485*4b9c6d91SCole Faust return -ERANGE;
486*4b9c6d91SCole Faust }
487*4b9c6d91SCole Faust
seccomp_action_is_available(const char * wanted)488*4b9c6d91SCole Faust static bool seccomp_action_is_available(const char *wanted)
489*4b9c6d91SCole Faust {
490*4b9c6d91SCole Faust if (is_android()) {
491*4b9c6d91SCole Faust /*
492*4b9c6d91SCole Faust * Accessing |actions_avail| is generating SELinux denials, so
493*4b9c6d91SCole Faust * skip for now.
494*4b9c6d91SCole Faust * TODO(crbug.com/978022, jorgelo): Remove once the denial is
495*4b9c6d91SCole Faust * fixed.
496*4b9c6d91SCole Faust */
497*4b9c6d91SCole Faust return false;
498*4b9c6d91SCole Faust }
499*4b9c6d91SCole Faust const char actions_avail_path[] =
500*4b9c6d91SCole Faust "/proc/sys/kernel/seccomp/actions_avail";
501*4b9c6d91SCole Faust FILE *f = fopen(actions_avail_path, "re");
502*4b9c6d91SCole Faust
503*4b9c6d91SCole Faust if (!f) {
504*4b9c6d91SCole Faust pwarn("fopen(%s) failed", actions_avail_path);
505*4b9c6d91SCole Faust return false;
506*4b9c6d91SCole Faust }
507*4b9c6d91SCole Faust
508*4b9c6d91SCole Faust attribute_cleanup_str char *actions_avail = NULL;
509*4b9c6d91SCole Faust size_t buf_size = 0;
510*4b9c6d91SCole Faust if (getline(&actions_avail, &buf_size, f) < 0) {
511*4b9c6d91SCole Faust pwarn("getline() failed");
512*4b9c6d91SCole Faust return false;
513*4b9c6d91SCole Faust }
514*4b9c6d91SCole Faust
515*4b9c6d91SCole Faust /*
516*4b9c6d91SCole Faust * This is just substring search, which means that partial matches will
517*4b9c6d91SCole Faust * match too (e.g. "action" would match "longaction"). There are no
518*4b9c6d91SCole Faust * seccomp actions which include other actions though, so we're good for
519*4b9c6d91SCole Faust * now. Eventually we might want to split the string by spaces.
520*4b9c6d91SCole Faust */
521*4b9c6d91SCole Faust return strstr(actions_avail, wanted) != NULL;
522*4b9c6d91SCole Faust }
523*4b9c6d91SCole Faust
seccomp_ret_log_available(void)524*4b9c6d91SCole Faust int seccomp_ret_log_available(void)
525*4b9c6d91SCole Faust {
526*4b9c6d91SCole Faust static int ret_log_available = -1;
527*4b9c6d91SCole Faust
528*4b9c6d91SCole Faust if (ret_log_available == -1)
529*4b9c6d91SCole Faust ret_log_available = seccomp_action_is_available("log");
530*4b9c6d91SCole Faust
531*4b9c6d91SCole Faust return ret_log_available;
532*4b9c6d91SCole Faust }
533*4b9c6d91SCole Faust
seccomp_ret_kill_process_available(void)534*4b9c6d91SCole Faust int seccomp_ret_kill_process_available(void)
535*4b9c6d91SCole Faust {
536*4b9c6d91SCole Faust static int ret_kill_process_available = -1;
537*4b9c6d91SCole Faust
538*4b9c6d91SCole Faust if (ret_kill_process_available == -1)
539*4b9c6d91SCole Faust ret_kill_process_available =
540*4b9c6d91SCole Faust seccomp_action_is_available("kill_process");
541*4b9c6d91SCole Faust
542*4b9c6d91SCole Faust return ret_kill_process_available;
543*4b9c6d91SCole Faust }
544*4b9c6d91SCole Faust
seccomp_filter_flags_available(unsigned int flags)545*4b9c6d91SCole Faust bool seccomp_filter_flags_available(unsigned int flags)
546*4b9c6d91SCole Faust {
547*4b9c6d91SCole Faust return sys_seccomp(SECCOMP_SET_MODE_FILTER, flags, NULL) != -1 ||
548*4b9c6d91SCole Faust errno != EINVAL;
549*4b9c6d91SCole Faust }
550*4b9c6d91SCole Faust
is_canonical_path(const char * path)551*4b9c6d91SCole Faust bool is_canonical_path(const char *path)
552*4b9c6d91SCole Faust {
553*4b9c6d91SCole Faust attribute_cleanup_str char *rp = realpath(path, NULL);
554*4b9c6d91SCole Faust if (!rp) {
555*4b9c6d91SCole Faust return false;
556*4b9c6d91SCole Faust }
557*4b9c6d91SCole Faust
558*4b9c6d91SCole Faust if (streq(path, rp)) {
559*4b9c6d91SCole Faust return true;
560*4b9c6d91SCole Faust }
561*4b9c6d91SCole Faust
562*4b9c6d91SCole Faust size_t path_len = strlen(path);
563*4b9c6d91SCole Faust size_t rp_len = strlen(rp);
564*4b9c6d91SCole Faust /* If |path| has a single trailing slash, that's OK. */
565*4b9c6d91SCole Faust return path_len == rp_len + 1 && strncmp(path, rp, rp_len) == 0 &&
566*4b9c6d91SCole Faust path[path_len - 1] == '/';
567*4b9c6d91SCole Faust }
568