54 #include "opt_capsicum.h"
56 #include <sys/cdefs.h>
59 #include <sys/param.h>
60 #include <sys/capability.h>
62 #include <sys/filedesc.h>
63 #include <sys/kernel.h>
65 #include <sys/mutex.h>
67 #include <sys/sysproto.h>
68 #include <sys/sysctl.h>
69 #include <sys/systm.h>
70 #include <sys/ucred.h>
72 #include <security/audit/audit.h>
77 #ifdef CAPABILITY_MODE
79 FEATURE(security_capability_mode,
"Capsicum Capability Mode");
87 struct ucred *newcred, *oldcred;
90 if (IN_CAPABILITY_MODE(td))
98 newcred->cr_flags |= CRED_FLAG_CAPMODE;
113 i = (IN_CAPABILITY_MODE(td)) ? 1 : 0;
114 return (copyout(&i, uap->modep,
sizeof(i)));
137 FEATURE(security_capabilities,
"Capsicum Capabilities");
146 struct file *cap_object;
147 struct file *cap_file;
148 cap_rights_t cap_rights;
156 static fo_rdwr_t capability_read;
157 static fo_rdwr_t capability_write;
158 static fo_truncate_t capability_truncate;
159 static fo_ioctl_t capability_ioctl;
160 static fo_poll_t capability_poll;
161 static fo_kqfilter_t capability_kqfilter;
162 static fo_stat_t capability_stat;
163 static fo_close_t capability_close;
164 static fo_chmod_t capability_chmod;
165 static fo_chown_t capability_chown;
167 static struct fileops capability_ops = {
168 .fo_read = capability_read,
169 .fo_write = capability_write,
170 .fo_truncate = capability_truncate,
171 .fo_ioctl = capability_ioctl,
172 .fo_poll = capability_poll,
173 .fo_kqfilter = capability_kqfilter,
174 .fo_stat = capability_stat,
175 .fo_close = capability_close,
176 .fo_chmod = capability_chmod,
177 .fo_chown = capability_chown,
178 .fo_flags = DFLAG_PASSABLE,
181 static struct fileops capability_ops_unpassable = {
182 .fo_read = capability_read,
183 .fo_write = capability_write,
184 .fo_truncate = capability_truncate,
185 .fo_ioctl = capability_ioctl,
186 .fo_poll = capability_poll,
187 .fo_kqfilter = capability_kqfilter,
188 .fo_stat = capability_stat,
189 .fo_close = capability_close,
190 .fo_chmod = capability_chmod,
191 .fo_chown = capability_chown,
195 static uma_zone_t capability_zone;
198 capability_init(
void *
dummy __unused)
201 capability_zone = uma_zcreate(
"capability",
sizeof(
struct capability),
202 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
203 if (capability_zone == NULL)
204 panic(
"capability_init: capability_zone not initialized");
206 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, capability_init, NULL);
212 cap_check(
struct capability *c, cap_rights_t rights)
215 if ((c->cap_rights | rights) != c->cap_rights)
216 return (ENOTCAPABLE);
226 cap_rights(
struct file *fp_cap)
228 struct capability *c;
230 KASSERT(fp_cap->f_type == DTYPE_CAPABILITY,
231 (
"cap_rights: !capability"));
234 return (c->cap_rights);
242 sys_cap_new(
struct thread *td,
struct cap_new_args *uap)
247 cap_rights_t rights = uap->rights;
250 AUDIT_ARG_RIGHTS(rights);
251 error =
fget(td, fd, rights, &fp);
254 AUDIT_ARG_FILE(td->td_proc, fp);
255 error = kern_capwrap(td, fp, rights, &capfd);
262 td->td_retval[0] = capfd;
272 struct capability *cp;
276 AUDIT_ARG_FD(uap->fd);
277 error =
fgetcap(td, uap->fd, &fp);
281 error = copyout(&cp->cap_rights, uap->rightsp,
sizeof(*uap->rightsp));
290 kern_capwrap(
struct thread *td,
struct file *fp, cap_rights_t rights,
293 struct capability *cp, *cp_old;
294 struct file *fp_object, *fcapp;
297 if ((rights | CAP_MASK_VALID) != CAP_MASK_VALID)
305 if (fp->f_type == DTYPE_CAPABILITY) {
307 if ((cp_old->cap_rights | rights) != cp_old->cap_rights)
308 return (ENOTCAPABLE);
314 error =
falloc(td, &fcapp, capfdp, fp->f_flag);
325 if (fp->f_type == DTYPE_CAPABILITY)
326 fp_object = ((
struct capability *)fp->f_data)->cap_object;
330 cp = uma_zalloc(capability_zone, M_WAITOK | M_ZERO);
331 cp->cap_rights = rights;
332 cp->cap_object = fp_object;
333 cp->cap_file = fcapp;
334 if (fp->f_flag & DFLAG_PASSABLE)
335 finit(fcapp, fp->f_flag, DTYPE_CAPABILITY, cp,
338 finit(fcapp, fp->f_flag, DTYPE_CAPABILITY, cp,
339 &capability_ops_unpassable);
357 cap_funwrap(
struct file *fp_cap, cap_rights_t rights,
struct file **fpp)
359 struct capability *c;
362 if (fp_cap->f_type != DTYPE_CAPABILITY) {
367 error = cap_check(c, rights);
370 *fpp = c->cap_object;
380 cap_funwrap_mmap(
struct file *fp_cap, cap_rights_t rights, u_char *maxprotp,
383 struct capability *c;
387 if (fp_cap->f_type != DTYPE_CAPABILITY) {
389 *maxprotp = VM_PROT_ALL;
393 error = cap_check(c, rights | CAP_MMAP);
396 *fpp = c->cap_object;
398 if (c->cap_rights & CAP_READ)
399 maxprot |= VM_PROT_READ;
400 if (c->cap_rights & CAP_WRITE)
401 maxprot |= VM_PROT_WRITE;
402 if (c->cap_rights & CAP_MAPEXEC)
403 maxprot |= VM_PROT_EXECUTE;
415 capability_close(
struct file *fp,
struct thread *td)
417 struct capability *c;
418 struct file *fp_object;
420 KASSERT(fp->f_type == DTYPE_CAPABILITY,
421 (
"capability_close: !capability"));
426 fp_object = c->cap_object;
427 uma_zfree(capability_zone, c);
428 return (fdrop(fp_object, td));
437 capability_read(
struct file *fp,
struct uio *uio,
struct ucred *active_cred,
438 int flags,
struct thread *td)
441 panic(
"capability_read");
445 capability_write(
struct file *fp,
struct uio *uio,
struct ucred *active_cred,
446 int flags,
struct thread *td)
449 panic(
"capability_write");
453 capability_truncate(
struct file *fp, off_t length,
struct ucred *active_cred,
457 panic(
"capability_truncate");
461 capability_ioctl(
struct file *fp, u_long com,
void *data,
462 struct ucred *active_cred,
struct thread *td)
465 panic(
"capability_ioctl");
469 capability_poll(
struct file *fp,
int events,
struct ucred *active_cred,
473 panic(
"capability_poll");
477 capability_kqfilter(
struct file *fp,
struct knote *kn)
480 panic(
"capability_kqfilter");
484 capability_stat(
struct file *fp,
struct stat *sb,
struct ucred *active_cred,
488 panic(
"capability_stat");
492 capability_chmod(
struct file *fp, mode_t
mode,
struct ucred *active_cred,
496 panic(
"capability_chmod");
500 capability_chown(
struct file *fp, uid_t uid, gid_t gid,
501 struct ucred *active_cred,
struct thread *td)
504 panic(
"capability_chown");
528 cap_funwrap(
struct file *fp_cap, cap_rights_t rights,
struct file **fpp)
531 KASSERT(fp_cap->f_type != DTYPE_CAPABILITY,
532 (
"cap_funwrap: saw capability"));
543 KASSERT(fp_cap->f_type != DTYPE_CAPABILITY,
544 (
"cap_funwrap_mmap: saw capability"));
547 *maxprotp = VM_PROT_ALL;
int cap_funwrap(struct file *fp_cap, cap_rights_t rights, struct file **fpp)
int sys_cap_getmode(struct thread *td, struct cap_getmode_args *uap)
void panic(const char *fmt,...)
SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
void knote(struct knlist *list, long hint, int lockflags)
int fgetcap(struct thread *td, int fd, struct file **fpp)
int falloc(struct thread *td, struct file **resultfp, int *resultfd, int flags)
int fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp)
int sys_cap_new(struct thread *td, struct cap_new_args *uap)
void crfree(struct ucred *cr)
int sys_cap_getrights(struct thread *td, struct cap_getrights_args *uap)
int sys_cap_enter(struct thread *td, struct cap_enter_args *uap)
int cap_funwrap_mmap(struct file *fp_cap, cap_rights_t rights, u_char *maxprotp, struct file **fpp)
void finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops)
void crcopy(struct ucred *dest, struct ucred *src)
FEATURE(kdtrace_hooks,"Kernel DTrace hooks which are required to load DTrace kernel modules")
struct ucred * crget(void)
struct fileops badfileops