sys_capability.c revision 280258
1/*-
2 * Copyright (c) 2008-2011 Robert N. M. Watson
3 * Copyright (c) 2010-2011 Jonathan Anderson
4 * Copyright (c) 2012 FreeBSD Foundation
5 * All rights reserved.
6 *
7 * This software was developed at the University of Cambridge Computer
8 * Laboratory with support from a grant from Google, Inc.
9 *
10 * Portions of this software were developed by Pawel Jakub Dawidek under
11 * sponsorship from the FreeBSD Foundation.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * FreeBSD kernel capability facility.
37 *
38 * Two kernel features are implemented here: capability mode, a sandboxed mode
39 * of execution for processes, and capabilities, a refinement on file
40 * descriptors that allows fine-grained control over operations on the file
41 * descriptor.  Collectively, these allow processes to run in the style of a
42 * historic "capability system" in which they can use only resources
43 * explicitly delegated to them.  This model is enforced by restricting access
44 * to global namespaces in capability mode.
45 *
46 * Capabilities wrap other file descriptor types, binding them to a constant
47 * rights mask set when the capability is created.  New capabilities may be
48 * derived from existing capabilities, but only if they have the same or a
49 * strict subset of the rights on the original capability.
50 *
51 * System calls permitted in capability mode are defined in capabilities.conf;
52 * calls must be carefully audited for safety to ensure that they don't allow
53 * escape from a sandbox.  Some calls permit only a subset of operations in
54 * capability mode -- for example, shm_open(2) is limited to creating
55 * anonymous, rather than named, POSIX shared memory objects.
56 */
57
58#include <sys/cdefs.h>
59__FBSDID("$FreeBSD: stable/10/sys/kern/sys_capability.c 280258 2015-03-19 13:37:36Z rwatson $");
60
61#include "opt_capsicum.h"
62#include "opt_ktrace.h"
63
64#include <sys/param.h>
65#include <sys/capsicum.h>
66#include <sys/file.h>
67#include <sys/filedesc.h>
68#include <sys/kernel.h>
69#include <sys/limits.h>
70#include <sys/lock.h>
71#include <sys/mutex.h>
72#include <sys/proc.h>
73#include <sys/syscallsubr.h>
74#include <sys/sysproto.h>
75#include <sys/sysctl.h>
76#include <sys/systm.h>
77#include <sys/ucred.h>
78#include <sys/uio.h>
79#include <sys/ktrace.h>
80
81#include <security/audit/audit.h>
82
83#include <vm/uma.h>
84#include <vm/vm.h>
85
86#ifdef CAPABILITY_MODE
87
88FEATURE(security_capability_mode, "Capsicum Capability Mode");
89
90/*
91 * System call to enter capability mode for the process.
92 */
93int
94sys_cap_enter(struct thread *td, struct cap_enter_args *uap)
95{
96	struct ucred *newcred, *oldcred;
97	struct proc *p;
98
99	if (IN_CAPABILITY_MODE(td))
100		return (0);
101
102	newcred = crget();
103	p = td->td_proc;
104	PROC_LOCK(p);
105	oldcred = p->p_ucred;
106	crcopy(newcred, oldcred);
107	newcred->cr_flags |= CRED_FLAG_CAPMODE;
108	p->p_ucred = newcred;
109	PROC_UNLOCK(p);
110	crfree(oldcred);
111	return (0);
112}
113
114/*
115 * System call to query whether the process is in capability mode.
116 */
117int
118sys_cap_getmode(struct thread *td, struct cap_getmode_args *uap)
119{
120	u_int i;
121
122	i = IN_CAPABILITY_MODE(td) ? 1 : 0;
123	return (copyout(&i, uap->modep, sizeof(i)));
124}
125
126#else /* !CAPABILITY_MODE */
127
128int
129sys_cap_enter(struct thread *td, struct cap_enter_args *uap)
130{
131
132	return (ENOSYS);
133}
134
135int
136sys_cap_getmode(struct thread *td, struct cap_getmode_args *uap)
137{
138
139	return (ENOSYS);
140}
141
142#endif /* CAPABILITY_MODE */
143
144#ifdef CAPABILITIES
145
146FEATURE(security_capabilities, "Capsicum Capabilities");
147
148MALLOC_DECLARE(M_FILECAPS);
149
150static inline int
151_cap_check(const cap_rights_t *havep, const cap_rights_t *needp,
152    enum ktr_cap_fail_type type)
153{
154	int i;
155
156	for (i = 0; i < nitems(havep->cr_rights); i++) {
157		if (!cap_rights_contains(havep, needp)) {
158#ifdef KTRACE
159			if (KTRPOINT(curthread, KTR_CAPFAIL))
160				ktrcapfail(type, needp, havep);
161#endif
162			return (ENOTCAPABLE);
163		}
164	}
165	return (0);
166}
167
168/*
169 * Test whether a capability grants the requested rights.
170 */
171int
172cap_check(const cap_rights_t *havep, const cap_rights_t *needp)
173{
174
175	return (_cap_check(havep, needp, CAPFAIL_NOTCAPABLE));
176}
177
178/*
179 * Convert capability rights into VM access flags.
180 */
181u_char
182cap_rights_to_vmprot(cap_rights_t *havep)
183{
184	u_char maxprot;
185
186	maxprot = VM_PROT_NONE;
187	if (cap_rights_is_set(havep, CAP_MMAP_R))
188		maxprot |= VM_PROT_READ;
189	if (cap_rights_is_set(havep, CAP_MMAP_W))
190		maxprot |= VM_PROT_WRITE;
191	if (cap_rights_is_set(havep, CAP_MMAP_X))
192		maxprot |= VM_PROT_EXECUTE;
193
194	return (maxprot);
195}
196
197/*
198 * Extract rights from a capability for monitoring purposes -- not for use in
199 * any other way, as we want to keep all capability permission evaluation in
200 * this one file.
201 */
202
203cap_rights_t *
204cap_rights_fde(struct filedescent *fde)
205{
206
207	return (&fde->fde_rights);
208}
209
210cap_rights_t *
211cap_rights(struct filedesc *fdp, int fd)
212{
213
214	return (cap_rights_fde(&fdp->fd_ofiles[fd]));
215}
216
217/*
218 * System call to limit rights of the given capability.
219 */
220int
221sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
222{
223	struct filedesc *fdp;
224	cap_rights_t rights;
225	int error, fd, version;
226
227	cap_rights_init(&rights);
228
229	error = copyin(uap->rightsp, &rights, sizeof(rights.cr_rights[0]));
230	if (error != 0)
231		return (error);
232	version = CAPVER(&rights);
233	if (version != CAP_RIGHTS_VERSION_00)
234		return (EINVAL);
235
236	error = copyin(uap->rightsp, &rights,
237	    sizeof(rights.cr_rights[0]) * CAPARSIZE(&rights));
238	if (error != 0)
239		return (error);
240	/* Check for race. */
241	if (CAPVER(&rights) != version)
242		return (EINVAL);
243
244	if (!cap_rights_is_valid(&rights))
245		return (EINVAL);
246
247	if (version != CAP_RIGHTS_VERSION) {
248		rights.cr_rights[0] &= ~(0x3ULL << 62);
249		rights.cr_rights[0] |= ((uint64_t)CAP_RIGHTS_VERSION << 62);
250	}
251#ifdef KTRACE
252	if (KTRPOINT(td, KTR_STRUCT))
253		ktrcaprights(&rights);
254#endif
255
256	fd = uap->fd;
257
258	AUDIT_ARG_FD(fd);
259	AUDIT_ARG_RIGHTS(&rights);
260
261	fdp = td->td_proc->p_fd;
262	FILEDESC_XLOCK(fdp);
263	if (fget_locked(fdp, fd) == NULL) {
264		FILEDESC_XUNLOCK(fdp);
265		return (EBADF);
266	}
267	error = _cap_check(cap_rights(fdp, fd), &rights, CAPFAIL_INCREASE);
268	if (error == 0) {
269		fdp->fd_ofiles[fd].fde_rights = rights;
270		if (!cap_rights_is_set(&rights, CAP_IOCTL)) {
271			free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
272			fdp->fd_ofiles[fd].fde_ioctls = NULL;
273			fdp->fd_ofiles[fd].fde_nioctls = 0;
274		}
275		if (!cap_rights_is_set(&rights, CAP_FCNTL))
276			fdp->fd_ofiles[fd].fde_fcntls = 0;
277	}
278	FILEDESC_XUNLOCK(fdp);
279	return (error);
280}
281
282/*
283 * System call to query the rights mask associated with a capability.
284 */
285int
286sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap)
287{
288	struct filedesc *fdp;
289	cap_rights_t rights;
290	int error, fd, i, n;
291
292	if (uap->version != CAP_RIGHTS_VERSION_00)
293		return (EINVAL);
294
295	fd = uap->fd;
296
297	AUDIT_ARG_FD(fd);
298
299	fdp = td->td_proc->p_fd;
300	FILEDESC_SLOCK(fdp);
301	if (fget_locked(fdp, fd) == NULL) {
302		FILEDESC_SUNLOCK(fdp);
303		return (EBADF);
304	}
305	rights = *cap_rights(fdp, fd);
306	FILEDESC_SUNLOCK(fdp);
307	n = uap->version + 2;
308	if (uap->version != CAPVER(&rights)) {
309		/*
310		 * For older versions we need to check if the descriptor
311		 * doesn't contain rights not understood by the caller.
312		 * If it does, we have to return an error.
313		 */
314		for (i = n; i < CAPARSIZE(&rights); i++) {
315			if ((rights.cr_rights[i] & ~(0x7FULL << 57)) != 0)
316				return (EINVAL);
317		}
318	}
319	error = copyout(&rights, uap->rightsp, sizeof(rights.cr_rights[0]) * n);
320#ifdef KTRACE
321	if (error == 0 && KTRPOINT(td, KTR_STRUCT))
322		ktrcaprights(&rights);
323#endif
324	return (error);
325}
326
327/*
328 * Test whether a capability grants the given ioctl command.
329 * If descriptor doesn't have CAP_IOCTL, then ioctls list is empty and
330 * ENOTCAPABLE will be returned.
331 */
332int
333cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd)
334{
335	u_long *cmds;
336	ssize_t ncmds;
337	long i;
338
339	FILEDESC_LOCK_ASSERT(fdp);
340	KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
341	    ("%s: invalid fd=%d", __func__, fd));
342
343	ncmds = fdp->fd_ofiles[fd].fde_nioctls;
344	if (ncmds == -1)
345		return (0);
346
347	cmds = fdp->fd_ofiles[fd].fde_ioctls;
348	for (i = 0; i < ncmds; i++) {
349		if (cmds[i] == cmd)
350			return (0);
351	}
352
353	return (ENOTCAPABLE);
354}
355
356/*
357 * Check if the current ioctls list can be replaced by the new one.
358 */
359static int
360cap_ioctl_limit_check(struct filedesc *fdp, int fd, const u_long *cmds,
361    size_t ncmds)
362{
363	u_long *ocmds;
364	ssize_t oncmds;
365	u_long i;
366	long j;
367
368	oncmds = fdp->fd_ofiles[fd].fde_nioctls;
369	if (oncmds == -1)
370		return (0);
371	if (oncmds < (ssize_t)ncmds)
372		return (ENOTCAPABLE);
373
374	ocmds = fdp->fd_ofiles[fd].fde_ioctls;
375	for (i = 0; i < ncmds; i++) {
376		for (j = 0; j < oncmds; j++) {
377			if (cmds[i] == ocmds[j])
378				break;
379		}
380		if (j == oncmds)
381			return (ENOTCAPABLE);
382	}
383
384	return (0);
385}
386
387int
388kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds)
389{
390	struct filedesc *fdp;
391	u_long *ocmds;
392	int error;
393
394	AUDIT_ARG_FD(fd);
395
396	fdp = td->td_proc->p_fd;
397	FILEDESC_XLOCK(fdp);
398
399	if (fget_locked(fdp, fd) == NULL) {
400		error = EBADF;
401		goto out;
402	}
403
404	error = cap_ioctl_limit_check(fdp, fd, cmds, ncmds);
405	if (error != 0)
406		goto out;
407
408	ocmds = fdp->fd_ofiles[fd].fde_ioctls;
409	fdp->fd_ofiles[fd].fde_ioctls = cmds;
410	fdp->fd_ofiles[fd].fde_nioctls = ncmds;
411
412	cmds = ocmds;
413	error = 0;
414out:
415	FILEDESC_XUNLOCK(fdp);
416	free(cmds, M_FILECAPS);
417	return (error);
418}
419
420int
421sys_cap_ioctls_limit(struct thread *td, struct cap_ioctls_limit_args *uap)
422{
423	u_long *cmds;
424	size_t ncmds;
425	int error;
426
427	ncmds = uap->ncmds;
428
429	if (ncmds > 256)	/* XXX: Is 256 sane? */
430		return (EINVAL);
431
432	if (ncmds == 0) {
433		cmds = NULL;
434	} else {
435		cmds = malloc(sizeof(cmds[0]) * ncmds, M_FILECAPS, M_WAITOK);
436		error = copyin(uap->cmds, cmds, sizeof(cmds[0]) * ncmds);
437		if (error != 0) {
438			free(cmds, M_FILECAPS);
439			return (error);
440		}
441	}
442
443	return (kern_cap_ioctls_limit(td, uap->fd, cmds, ncmds));
444}
445
446int
447sys_cap_ioctls_get(struct thread *td, struct cap_ioctls_get_args *uap)
448{
449	struct filedesc *fdp;
450	struct filedescent *fdep;
451	u_long *cmds;
452	size_t maxcmds;
453	int error, fd;
454
455	fd = uap->fd;
456	cmds = uap->cmds;
457	maxcmds = uap->maxcmds;
458
459	AUDIT_ARG_FD(fd);
460
461	fdp = td->td_proc->p_fd;
462	FILEDESC_SLOCK(fdp);
463
464	if (fget_locked(fdp, fd) == NULL) {
465		error = EBADF;
466		goto out;
467	}
468
469	/*
470	 * If all ioctls are allowed (fde_nioctls == -1 && fde_ioctls == NULL)
471	 * the only sane thing we can do is to not populate the given array and
472	 * return CAP_IOCTLS_ALL.
473	 */
474
475	fdep = &fdp->fd_ofiles[fd];
476	if (cmds != NULL && fdep->fde_ioctls != NULL) {
477		error = copyout(fdep->fde_ioctls, cmds,
478		    sizeof(cmds[0]) * MIN(fdep->fde_nioctls, maxcmds));
479		if (error != 0)
480			goto out;
481	}
482	if (fdep->fde_nioctls == -1)
483		td->td_retval[0] = CAP_IOCTLS_ALL;
484	else
485		td->td_retval[0] = fdep->fde_nioctls;
486
487	error = 0;
488out:
489	FILEDESC_SUNLOCK(fdp);
490	return (error);
491}
492
493/*
494 * Test whether a capability grants the given fcntl command.
495 */
496int
497cap_fcntl_check_fde(struct filedescent *fde, int cmd)
498{
499	uint32_t fcntlcap;
500
501	fcntlcap = (1 << cmd);
502	KASSERT((CAP_FCNTL_ALL & fcntlcap) != 0,
503	    ("Unsupported fcntl=%d.", cmd));
504
505	if ((fde->fde_fcntls & fcntlcap) != 0)
506		return (0);
507
508	return (ENOTCAPABLE);
509}
510
511int
512cap_fcntl_check(struct filedesc *fdp, int fd, int cmd)
513{
514
515	KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
516	    ("%s: invalid fd=%d", __func__, fd));
517
518	return (cap_fcntl_check_fde(&fdp->fd_ofiles[fd], cmd));
519}
520
521int
522sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
523{
524	struct filedesc *fdp;
525	uint32_t fcntlrights;
526	int fd;
527
528	fd = uap->fd;
529	fcntlrights = uap->fcntlrights;
530
531	AUDIT_ARG_FD(fd);
532	AUDIT_ARG_FCNTL_RIGHTS(fcntlrights);
533
534	if ((fcntlrights & ~CAP_FCNTL_ALL) != 0)
535		return (EINVAL);
536
537	fdp = td->td_proc->p_fd;
538	FILEDESC_XLOCK(fdp);
539
540	if (fget_locked(fdp, fd) == NULL) {
541		FILEDESC_XUNLOCK(fdp);
542		return (EBADF);
543	}
544
545	if ((fcntlrights & ~fdp->fd_ofiles[fd].fde_fcntls) != 0) {
546		FILEDESC_XUNLOCK(fdp);
547		return (ENOTCAPABLE);
548	}
549
550	fdp->fd_ofiles[fd].fde_fcntls = fcntlrights;
551	FILEDESC_XUNLOCK(fdp);
552
553	return (0);
554}
555
556int
557sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
558{
559	struct filedesc *fdp;
560	uint32_t rights;
561	int fd;
562
563	fd = uap->fd;
564
565	AUDIT_ARG_FD(fd);
566
567	fdp = td->td_proc->p_fd;
568	FILEDESC_SLOCK(fdp);
569	if (fget_locked(fdp, fd) == NULL) {
570		FILEDESC_SUNLOCK(fdp);
571		return (EBADF);
572	}
573	rights = fdp->fd_ofiles[fd].fde_fcntls;
574	FILEDESC_SUNLOCK(fdp);
575
576	return (copyout(&rights, uap->fcntlrightsp, sizeof(rights)));
577}
578
579#else /* !CAPABILITIES */
580
581/*
582 * Stub Capability functions for when options CAPABILITIES isn't compiled
583 * into the kernel.
584 */
585
586int
587sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
588{
589
590	return (ENOSYS);
591}
592
593int
594sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap)
595{
596
597	return (ENOSYS);
598}
599
600int
601sys_cap_ioctls_limit(struct thread *td, struct cap_ioctls_limit_args *uap)
602{
603
604	return (ENOSYS);
605}
606
607int
608sys_cap_ioctls_get(struct thread *td, struct cap_ioctls_get_args *uap)
609{
610
611	return (ENOSYS);
612}
613
614int
615sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
616{
617
618	return (ENOSYS);
619}
620
621int
622sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
623{
624
625	return (ENOSYS);
626}
627
628#endif /* CAPABILITIES */
629