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