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