xref: /freebsd/sys/kern/sys_capability.c (revision 6dcefcac2b043be030851e03a721607b414b666b)
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$");
60 
61 #include "opt_capsicum.h"
62 #include "opt_ktrace.h"
63 
64 #include <sys/param.h>
65 #include <sys/capability.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/sysproto.h>
74 #include <sys/sysctl.h>
75 #include <sys/systm.h>
76 #include <sys/ucred.h>
77 #include <sys/uio.h>
78 #include <sys/ktrace.h>
79 
80 #include <security/audit/audit.h>
81 
82 #include <vm/uma.h>
83 #include <vm/vm.h>
84 
85 #ifdef CAPABILITY_MODE
86 
87 FEATURE(security_capability_mode, "Capsicum Capability Mode");
88 
89 /*
90  * System call to enter capability mode for the process.
91  */
92 int
93 sys_cap_enter(struct thread *td, struct cap_enter_args *uap)
94 {
95 	struct ucred *newcred, *oldcred;
96 	struct proc *p;
97 
98 	if (IN_CAPABILITY_MODE(td))
99 		return (0);
100 
101 	newcred = crget();
102 	p = td->td_proc;
103 	PROC_LOCK(p);
104 	oldcred = p->p_ucred;
105 	crcopy(newcred, oldcred);
106 	newcred->cr_flags |= CRED_FLAG_CAPMODE;
107 	p->p_ucred = newcred;
108 	PROC_UNLOCK(p);
109 	crfree(oldcred);
110 	return (0);
111 }
112 
113 /*
114  * System call to query whether the process is in capability mode.
115  */
116 int
117 sys_cap_getmode(struct thread *td, struct cap_getmode_args *uap)
118 {
119 	u_int i;
120 
121 	i = IN_CAPABILITY_MODE(td) ? 1 : 0;
122 	return (copyout(&i, uap->modep, sizeof(i)));
123 }
124 
125 #else /* !CAPABILITY_MODE */
126 
127 int
128 sys_cap_enter(struct thread *td, struct cap_enter_args *uap)
129 {
130 
131 	return (ENOSYS);
132 }
133 
134 int
135 sys_cap_getmode(struct thread *td, struct cap_getmode_args *uap)
136 {
137 
138 	return (ENOSYS);
139 }
140 
141 #endif /* CAPABILITY_MODE */
142 
143 #ifdef CAPABILITIES
144 
145 FEATURE(security_capabilities, "Capsicum Capabilities");
146 
147 MALLOC_DECLARE(M_FILECAPS);
148 
149 static inline int
150 _cap_check(cap_rights_t have, cap_rights_t need, enum ktr_cap_fail_type type)
151 {
152 
153 
154 	if ((need & ~have) != 0) {
155 #ifdef KTRACE
156 		if (KTRPOINT(curthread, KTR_CAPFAIL))
157 			ktrcapfail(type, need, have);
158 #endif
159 		return (ENOTCAPABLE);
160 	}
161 	return (0);
162 }
163 
164 /*
165  * Test whether a capability grants the requested rights.
166  */
167 int
168 cap_check(cap_rights_t have, cap_rights_t need)
169 {
170 
171 	return (_cap_check(have, need, CAPFAIL_NOTCAPABLE));
172 }
173 
174 /*
175  * Convert capability rights into VM access flags.
176  */
177 u_char
178 cap_rights_to_vmprot(cap_rights_t have)
179 {
180 	u_char maxprot;
181 
182 	maxprot = VM_PROT_NONE;
183 	if (have & CAP_MMAP_R)
184 		maxprot |= VM_PROT_READ;
185 	if (have & CAP_MMAP_W)
186 		maxprot |= VM_PROT_WRITE;
187 	if (have & CAP_MMAP_X)
188 		maxprot |= VM_PROT_EXECUTE;
189 
190 	return (maxprot);
191 }
192 
193 /*
194  * Extract rights from a capability for monitoring purposes -- not for use in
195  * any other way, as we want to keep all capability permission evaluation in
196  * this one file.
197  */
198 cap_rights_t
199 cap_rights(struct filedesc *fdp, int fd)
200 {
201 
202 	return (fdp->fd_ofiles[fd].fde_rights);
203 }
204 
205 /*
206  * System call to limit rights of the given capability.
207  */
208 int
209 sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
210 {
211 	struct filedesc *fdp;
212 	cap_rights_t rights;
213 	int error, fd;
214 
215 	fd = uap->fd;
216 	rights = uap->rights;
217 
218 	AUDIT_ARG_FD(fd);
219 	AUDIT_ARG_RIGHTS(rights);
220 
221 	if ((rights & ~CAP_ALL) != 0)
222 		return (EINVAL);
223 
224 	fdp = td->td_proc->p_fd;
225 	FILEDESC_XLOCK(fdp);
226 	if (fget_locked(fdp, fd) == NULL) {
227 		FILEDESC_XUNLOCK(fdp);
228 		return (EBADF);
229 	}
230 	error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
231 	if (error == 0) {
232 		fdp->fd_ofiles[fd].fde_rights = rights;
233 		if ((rights & CAP_IOCTL) == 0) {
234 			free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
235 			fdp->fd_ofiles[fd].fde_ioctls = NULL;
236 			fdp->fd_ofiles[fd].fde_nioctls = 0;
237 		}
238 		if ((rights & CAP_FCNTL) == 0)
239 			fdp->fd_ofiles[fd].fde_fcntls = 0;
240 	}
241 	FILEDESC_XUNLOCK(fdp);
242 	return (error);
243 }
244 
245 /*
246  * System call to query the rights mask associated with a capability.
247  */
248 int
249 sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap)
250 {
251 	struct filedesc *fdp;
252 	cap_rights_t rights;
253 	int fd;
254 
255 	fd = uap->fd;
256 
257 	AUDIT_ARG_FD(fd);
258 
259 	fdp = td->td_proc->p_fd;
260 	FILEDESC_SLOCK(fdp);
261 	if (fget_locked(fdp, fd) == NULL) {
262 		FILEDESC_SUNLOCK(fdp);
263 		return (EBADF);
264 	}
265 	rights = cap_rights(fdp, fd);
266 	FILEDESC_SUNLOCK(fdp);
267 	return (copyout(&rights, uap->rightsp, sizeof(*uap->rightsp)));
268 }
269 
270 /*
271  * Test whether a capability grants the given ioctl command.
272  * If descriptor doesn't have CAP_IOCTL, then ioctls list is empty and
273  * ENOTCAPABLE will be returned.
274  */
275 int
276 cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd)
277 {
278 	u_long *cmds;
279 	ssize_t ncmds;
280 	long i;
281 
282 	FILEDESC_LOCK_ASSERT(fdp);
283 	KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
284 	    ("%s: invalid fd=%d", __func__, fd));
285 
286 	ncmds = fdp->fd_ofiles[fd].fde_nioctls;
287 	if (ncmds == -1)
288 		return (0);
289 
290 	cmds = fdp->fd_ofiles[fd].fde_ioctls;
291 	for (i = 0; i < ncmds; i++) {
292 		if (cmds[i] == cmd)
293 			return (0);
294 	}
295 
296 	return (ENOTCAPABLE);
297 }
298 
299 /*
300  * Check if the current ioctls list can be replaced by the new one.
301  */
302 static int
303 cap_ioctl_limit_check(struct filedesc *fdp, int fd, const u_long *cmds,
304     size_t ncmds)
305 {
306 	u_long *ocmds;
307 	ssize_t oncmds;
308 	u_long i;
309 	long j;
310 
311 	oncmds = fdp->fd_ofiles[fd].fde_nioctls;
312 	if (oncmds == -1)
313 		return (0);
314 	if (oncmds < (ssize_t)ncmds)
315 		return (ENOTCAPABLE);
316 
317 	ocmds = fdp->fd_ofiles[fd].fde_ioctls;
318 	for (i = 0; i < ncmds; i++) {
319 		for (j = 0; j < oncmds; j++) {
320 			if (cmds[i] == ocmds[j])
321 				break;
322 		}
323 		if (j == oncmds)
324 			return (ENOTCAPABLE);
325 	}
326 
327 	return (0);
328 }
329 
330 int
331 sys_cap_ioctls_limit(struct thread *td, struct cap_ioctls_limit_args *uap)
332 {
333 	struct filedesc *fdp;
334 	u_long *cmds, *ocmds;
335 	size_t ncmds;
336 	int error, fd;
337 
338 	fd = uap->fd;
339 	ncmds = uap->ncmds;
340 
341 	AUDIT_ARG_FD(fd);
342 
343 	if (ncmds > 256)	/* XXX: Is 256 sane? */
344 		return (EINVAL);
345 
346 	if (ncmds == 0) {
347 		cmds = NULL;
348 	} else {
349 		cmds = malloc(sizeof(cmds[0]) * ncmds, M_FILECAPS, M_WAITOK);
350 		error = copyin(uap->cmds, cmds, sizeof(cmds[0]) * ncmds);
351 		if (error != 0) {
352 			free(cmds, M_FILECAPS);
353 			return (error);
354 		}
355 	}
356 
357 	fdp = td->td_proc->p_fd;
358 	FILEDESC_XLOCK(fdp);
359 
360 	if (fget_locked(fdp, fd) == NULL) {
361 		error = EBADF;
362 		goto out;
363 	}
364 
365 	error = cap_ioctl_limit_check(fdp, fd, cmds, ncmds);
366 	if (error != 0)
367 		goto out;
368 
369 	ocmds = fdp->fd_ofiles[fd].fde_ioctls;
370 	fdp->fd_ofiles[fd].fde_ioctls = cmds;
371 	fdp->fd_ofiles[fd].fde_nioctls = ncmds;
372 
373 	cmds = ocmds;
374 	error = 0;
375 out:
376 	FILEDESC_XUNLOCK(fdp);
377 	free(cmds, M_FILECAPS);
378 	return (error);
379 }
380 
381 int
382 sys_cap_ioctls_get(struct thread *td, struct cap_ioctls_get_args *uap)
383 {
384 	struct filedesc *fdp;
385 	struct filedescent *fdep;
386 	u_long *cmds;
387 	size_t maxcmds;
388 	int error, fd;
389 
390 	fd = uap->fd;
391 	cmds = uap->cmds;
392 	maxcmds = uap->maxcmds;
393 
394 	AUDIT_ARG_FD(fd);
395 
396 	fdp = td->td_proc->p_fd;
397 	FILEDESC_SLOCK(fdp);
398 
399 	if (fget_locked(fdp, fd) == NULL) {
400 		error = EBADF;
401 		goto out;
402 	}
403 
404 	/*
405 	 * If all ioctls are allowed (fde_nioctls == -1 && fde_ioctls == NULL)
406 	 * the only sane thing we can do is to not populate the given array and
407 	 * return CAP_IOCTLS_ALL.
408 	 */
409 
410 	fdep = &fdp->fd_ofiles[fd];
411 	if (cmds != NULL && fdep->fde_ioctls != NULL) {
412 		error = copyout(fdep->fde_ioctls, cmds,
413 		    sizeof(cmds[0]) * MIN(fdep->fde_nioctls, maxcmds));
414 		if (error != 0)
415 			goto out;
416 	}
417 	if (fdep->fde_nioctls == -1)
418 		td->td_retval[0] = CAP_IOCTLS_ALL;
419 	else
420 		td->td_retval[0] = fdep->fde_nioctls;
421 
422 	error = 0;
423 out:
424 	FILEDESC_SUNLOCK(fdp);
425 	return (error);
426 }
427 
428 /*
429  * Test whether a capability grants the given fcntl command.
430  */
431 int
432 cap_fcntl_check(struct filedesc *fdp, int fd, int cmd)
433 {
434 	uint32_t fcntlcap;
435 
436 	KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
437 	    ("%s: invalid fd=%d", __func__, fd));
438 
439 	fcntlcap = (1 << cmd);
440 	KASSERT((CAP_FCNTL_ALL & fcntlcap) != 0,
441 	    ("Unsupported fcntl=%d.", cmd));
442 
443 	if ((fdp->fd_ofiles[fd].fde_fcntls & fcntlcap) != 0)
444 		return (0);
445 
446 	return (ENOTCAPABLE);
447 }
448 
449 int
450 sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
451 {
452 	struct filedesc *fdp;
453 	uint32_t fcntlrights;
454 	int fd;
455 
456 	fd = uap->fd;
457 	fcntlrights = uap->fcntlrights;
458 
459 	AUDIT_ARG_FD(fd);
460 	AUDIT_ARG_FCNTL_RIGHTS(fcntlrights);
461 
462 	if ((fcntlrights & ~CAP_FCNTL_ALL) != 0)
463 		return (EINVAL);
464 
465 	fdp = td->td_proc->p_fd;
466 	FILEDESC_XLOCK(fdp);
467 
468 	if (fget_locked(fdp, fd) == NULL) {
469 		FILEDESC_XUNLOCK(fdp);
470 		return (EBADF);
471 	}
472 
473 	if ((fcntlrights & ~fdp->fd_ofiles[fd].fde_fcntls) != 0) {
474 		FILEDESC_XUNLOCK(fdp);
475 		return (ENOTCAPABLE);
476 	}
477 
478 	fdp->fd_ofiles[fd].fde_fcntls = fcntlrights;
479 	FILEDESC_XUNLOCK(fdp);
480 
481 	return (0);
482 }
483 
484 int
485 sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
486 {
487 	struct filedesc *fdp;
488 	uint32_t rights;
489 	int fd;
490 
491 	fd = uap->fd;
492 
493 	AUDIT_ARG_FD(fd);
494 
495 	fdp = td->td_proc->p_fd;
496 	FILEDESC_SLOCK(fdp);
497 	if (fget_locked(fdp, fd) == NULL) {
498 		FILEDESC_SUNLOCK(fdp);
499 		return (EBADF);
500 	}
501 	rights = fdp->fd_ofiles[fd].fde_fcntls;
502 	FILEDESC_SUNLOCK(fdp);
503 
504 	return (copyout(&rights, uap->fcntlrightsp, sizeof(rights)));
505 }
506 
507 /*
508  * For backward compatibility.
509  */
510 int
511 sys_cap_new(struct thread *td, struct cap_new_args *uap)
512 {
513 	struct filedesc *fdp;
514 	cap_rights_t rights;
515 	register_t newfd;
516 	int error, fd;
517 
518 	fd = uap->fd;
519 	rights = uap->rights;
520 
521 	AUDIT_ARG_FD(fd);
522 	AUDIT_ARG_RIGHTS(rights);
523 
524 	if ((rights & ~CAP_ALL) != 0)
525 		return (EINVAL);
526 
527 	fdp = td->td_proc->p_fd;
528 	FILEDESC_SLOCK(fdp);
529 	if (fget_locked(fdp, fd) == NULL) {
530 		FILEDESC_SUNLOCK(fdp);
531 		return (EBADF);
532 	}
533 	error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
534 	FILEDESC_SUNLOCK(fdp);
535 	if (error != 0)
536 		return (error);
537 
538 	error = do_dup(td, 0, fd, 0, &newfd);
539 	if (error != 0)
540 		return (error);
541 
542 	FILEDESC_XLOCK(fdp);
543 	/*
544 	 * We don't really care about the race between checking capability
545 	 * rights for the source descriptor and now. If capability rights
546 	 * were ok at that earlier point, the process had this descriptor
547 	 * with those rights, so we don't increase them in security sense,
548 	 * the process might have done the cap_new(2) a bit earlier to get
549 	 * the same effect.
550 	 */
551 	fdp->fd_ofiles[newfd].fde_rights = rights;
552 	if ((rights & CAP_IOCTL) == 0) {
553 		free(fdp->fd_ofiles[newfd].fde_ioctls, M_FILECAPS);
554 		fdp->fd_ofiles[newfd].fde_ioctls = NULL;
555 		fdp->fd_ofiles[newfd].fde_nioctls = 0;
556 	}
557 	if ((rights & CAP_FCNTL) == 0)
558 		fdp->fd_ofiles[newfd].fde_fcntls = 0;
559 	FILEDESC_XUNLOCK(fdp);
560 
561 	td->td_retval[0] = newfd;
562 
563 	return (0);
564 }
565 
566 #else /* !CAPABILITIES */
567 
568 /*
569  * Stub Capability functions for when options CAPABILITIES isn't compiled
570  * into the kernel.
571  */
572 
573 int
574 sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
575 {
576 
577 	return (ENOSYS);
578 }
579 
580 int
581 sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap)
582 {
583 
584 	return (ENOSYS);
585 }
586 
587 int
588 sys_cap_ioctls_limit(struct thread *td, struct cap_ioctls_limit_args *uap)
589 {
590 
591 	return (ENOSYS);
592 }
593 
594 int
595 sys_cap_ioctls_get(struct thread *td, struct cap_ioctls_get_args *uap)
596 {
597 
598 	return (ENOSYS);
599 }
600 
601 int
602 sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
603 {
604 
605 	return (ENOSYS);
606 }
607 
608 int
609 sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
610 {
611 
612 	return (ENOSYS);
613 }
614 
615 int
616 sys_cap_new(struct thread *td, struct cap_new_args *uap)
617 {
618 
619 	return (ENOSYS);
620 }
621 
622 #endif /* CAPABILITIES */
623