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