]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/sys_capability.c
- Add a general purpose resource allocator, vmem, from NetBSD. It was
[FreeBSD/FreeBSD.git] / sys / kern / sys_capability.c
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 */