Add additional preinitialized cap_rights

This commit is contained in:
Matt Macy 2018-05-20 05:13:12 +00:00
parent 58a0f0d00c
commit 7118990962
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333920
3 changed files with 74 additions and 50 deletions

View File

@ -55,31 +55,47 @@ __FBSDID("$FreeBSD$");
#define assert(exp) KASSERT((exp), ("%s:%u", __func__, __LINE__))
__read_mostly cap_rights_t cap_accept_rights;
__read_mostly cap_rights_t cap_bind_rights;
__read_mostly cap_rights_t cap_chflags_rights;
__read_mostly cap_rights_t cap_connect_rights;
__read_mostly cap_rights_t cap_event_rights;
__read_mostly cap_rights_t cap_fchdir_rights;
__read_mostly cap_rights_t cap_fchflags_rights;
__read_mostly cap_rights_t cap_fchmod_rights;
__read_mostly cap_rights_t cap_fchown_rights;
__read_mostly cap_rights_t cap_fcntl_rights;
__read_mostly cap_rights_t cap_fexecve_rights;
__read_mostly cap_rights_t cap_flock_rights;
__read_mostly cap_rights_t cap_fpathconf_rights;
__read_mostly cap_rights_t cap_fstat_rights;
__read_mostly cap_rights_t cap_fstatfs_rights;
__read_mostly cap_rights_t cap_fsync_rights;
__read_mostly cap_rights_t cap_ftruncate_rights;
__read_mostly cap_rights_t cap_futimes_rights;
__read_mostly cap_rights_t cap_getpeername_rights;
__read_mostly cap_rights_t cap_getsockopt_rights;
__read_mostly cap_rights_t cap_getsockname_rights;
__read_mostly cap_rights_t cap_ioctl_rights;
__read_mostly cap_rights_t cap_listen_rights;
__read_mostly cap_rights_t cap_linkat_source_rights;
__read_mostly cap_rights_t cap_linkat_target_rights;
__read_mostly cap_rights_t cap_mmap_rights;
__read_mostly cap_rights_t cap_fsync_rights;
__read_mostly cap_rights_t cap_mkdirat_rights;
__read_mostly cap_rights_t cap_mkfifoat_rights;
__read_mostly cap_rights_t cap_mknodat_rights;
__read_mostly cap_rights_t cap_pdgetpid_rights;
__read_mostly cap_rights_t cap_pdkill_rights;
__read_mostly cap_rights_t cap_pread_rights;
__read_mostly cap_rights_t cap_pwrite_rights;
__read_mostly cap_rights_t cap_read_rights;
__read_mostly cap_rights_t cap_recv_rights;
__read_mostly cap_rights_t cap_renameat_source_rights;
__read_mostly cap_rights_t cap_renameat_target_rights;
__read_mostly cap_rights_t cap_seek_rights;
__read_mostly cap_rights_t cap_send_rights;
__read_mostly cap_rights_t cap_setsockopt_rights;
__read_mostly cap_rights_t cap_shutdown_rights;
__read_mostly cap_rights_t cap_symlinkat_rights;
__read_mostly cap_rights_t cap_unlinkat_rights;
__read_mostly cap_rights_t cap_write_rights;
__read_mostly cap_rights_t cap_no_rights;
@ -91,18 +107,28 @@ __cap_rights_sysinit1(void *arg)
cap_rights_init(&cap_connect_rights, CAP_CONNECT);
cap_rights_init(&cap_event_rights, CAP_EVENT);
cap_rights_init(&cap_fchdir_rights, CAP_FCHDIR);
cap_rights_init(&cap_fchflags_rights, CAP_FCHFLAGS);
cap_rights_init(&cap_fchmod_rights, CAP_FCHMOD);
cap_rights_init(&cap_fchown_rights, CAP_FCHOWN);
cap_rights_init(&cap_fcntl_rights, CAP_FCNTL);
cap_rights_init(&cap_fexecve_rights, CAP_FEXECVE);
cap_rights_init(&cap_flock_rights, CAP_FLOCK);
cap_rights_init(&cap_fpathconf_rights, CAP_FPATHCONF);
cap_rights_init(&cap_fstat_rights, CAP_FSTAT);
cap_rights_init(&cap_fstatfs_rights, CAP_FSTATFS);
cap_rights_init(&cap_fsync_rights, CAP_FSYNC);
cap_rights_init(&cap_ftruncate_rights, CAP_FTRUNCATE);
cap_rights_init(&cap_futimes_rights, CAP_FUTIMES);
cap_rights_init(&cap_getpeername_rights, CAP_GETPEERNAME);
cap_rights_init(&cap_getsockname_rights, CAP_GETSOCKNAME);
cap_rights_init(&cap_getsockopt_rights, CAP_GETSOCKOPT);
cap_rights_init(&cap_ioctl_rights, CAP_IOCTL);
cap_rights_init(&cap_linkat_source_rights, CAP_LINKAT_SOURCE);
cap_rights_init(&cap_linkat_target_rights, CAP_LINKAT_TARGET);
cap_rights_init(&cap_listen_rights, CAP_LISTEN);
cap_rights_init(&cap_mkdirat_rights, CAP_MKDIRAT);
cap_rights_init(&cap_mkfifoat_rights, CAP_MKFIFOAT);
cap_rights_init(&cap_mknodat_rights, CAP_MKNODAT);
cap_rights_init(&cap_mmap_rights, CAP_MMAP);
cap_rights_init(&cap_pdgetpid_rights, CAP_PDGETPID);
cap_rights_init(&cap_pdkill_rights, CAP_PDKILL);
@ -110,9 +136,14 @@ __cap_rights_sysinit1(void *arg)
cap_rights_init(&cap_pwrite_rights, CAP_PWRITE);
cap_rights_init(&cap_read_rights, CAP_READ);
cap_rights_init(&cap_recv_rights, CAP_RECV);
cap_rights_init(&cap_renameat_source_rights, CAP_RENAMEAT_SOURCE);
cap_rights_init(&cap_renameat_target_rights, CAP_RENAMEAT_TARGET);
cap_rights_init(&cap_seek_rights, CAP_SEEK);
cap_rights_init(&cap_send_rights, CAP_SEND);
cap_rights_init(&cap_setsockopt_rights, CAP_SETSOCKOPT);
cap_rights_init(&cap_shutdown_rights, CAP_SHUTDOWN);
cap_rights_init(&cap_symlinkat_rights, CAP_SYMLINKAT);
cap_rights_init(&cap_unlinkat_rights, CAP_UNLINKAT);
cap_rights_init(&cap_write_rights, CAP_WRITE);
cap_rights_init(&cap_no_rights);
}

View File

@ -345,11 +345,10 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
struct file *fp;
struct mount *mp;
struct vnode *vp;
cap_rights_t rights;
int error;
AUDIT_ARG_FD(fd);
error = getvnode(td, fd, cap_rights_init(&rights, CAP_FSTATFS), &fp);
error = getvnode(td, fd, &cap_fstatfs_rights, &fp);
if (error != 0)
return (error);
vp = fp->f_vnode;
@ -1236,7 +1235,6 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
struct mount *mp;
struct vattr vattr;
struct nameidata nd;
cap_rights_t rights;
int error, whiteout = 0;
AUDIT_ARG_MODE(mode);
@ -1264,7 +1262,7 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT),
NOCACHE, pathseg, path, fd, &cap_mknodat_rights,
td);
if ((error = namei(&nd)) != 0)
return (error);
@ -1365,14 +1363,13 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
struct mount *mp;
struct vattr vattr;
struct nameidata nd;
cap_rights_t rights;
int error;
AUDIT_ARG_MODE(mode);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT),
NOCACHE, pathseg, path, fd, &cap_mkfifoat_rights,
td);
if ((error = namei(&nd)) != 0)
return (error);
@ -1498,13 +1495,12 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
struct vnode *vp;
struct mount *mp;
struct nameidata nd;
cap_rights_t rights;
int error;
again:
bwillwrite();
NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, segflg, path1, fd1,
cap_rights_init(&rights, CAP_LINKAT_SOURCE), td);
&cap_linkat_source_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@ -1516,7 +1512,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
}
NDINIT_ATRIGHTS(&nd, CREATE,
LOCKPARENT | SAVENAME | AUDITVNODE2 | NOCACHE, segflg, path2, fd2,
cap_rights_init(&rights, CAP_LINKAT_TARGET), td);
&cap_linkat_target_rights, td);
if ((error = namei(&nd)) == 0) {
if (nd.ni_vp != NULL) {
NDFREE(&nd, NDF_ONLY_PNBUF);
@ -1618,7 +1614,6 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2,
char *syspath;
struct nameidata nd;
int error;
cap_rights_t rights;
if (segflg == UIO_SYSSPACE) {
syspath = path1;
@ -1631,7 +1626,7 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2,
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
NOCACHE, segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT),
NOCACHE, segflg, path2, fd, &cap_symlinkat_rights,
td);
if ((error = namei(&nd)) != 0)
goto out;
@ -1769,13 +1764,12 @@ kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
struct vnode *vp;
struct nameidata nd;
struct stat sb;
cap_rights_t rights;
int error;
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1,
pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td);
pathseg, path, fd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0)
return (error == EINVAL ? EPERM : error);
vp = nd.ni_vp;
@ -1851,11 +1845,10 @@ int
kern_lseek(struct thread *td, int fd, off_t offset, int whence)
{
struct file *fp;
cap_rights_t rights;
int error;
AUDIT_ARG_FD(fd);
error = fget(td, fd, cap_rights_init(&rights, CAP_SEEK), &fp);
error = fget(td, fd, &cap_seek_rights, &fp);
if (error != 0)
return (error);
error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ?
@ -1964,7 +1957,6 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
struct ucred *cred, *usecred;
struct vnode *vp;
struct nameidata nd;
cap_rights_t rights;
int error;
if (flag & ~AT_EACCESS)
@ -1988,7 +1980,7 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
usecred = cred;
AUDIT_ARG_VALUE(amode);
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF |
AUDITVNODE1, pathseg, path, fd, cap_rights_init(&rights, CAP_FSTAT),
AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights,
td);
if ((error = namei(&nd)) != 0)
goto out;
@ -2609,13 +2601,12 @@ kern_chflagsat(struct thread *td, int fd, const char *path,
enum uio_seg pathseg, u_long flags, int atflag)
{
struct nameidata nd;
cap_rights_t rights;
int error, follow;
AUDIT_ARG_FFLAGS(flags);
follow = (atflag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
cap_rights_init(&rights, CAP_FCHFLAGS), td);
&cap_fchflags_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
@ -2637,12 +2628,11 @@ int
sys_fchflags(struct thread *td, struct fchflags_args *uap)
{
struct file *fp;
cap_rights_t rights;
int error;
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_FFLAGS(uap->flags);
error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_FCHFLAGS),
error = getvnode(td, uap->fd, &cap_fchflags_rights,
&fp);
if (error != 0)
return (error);
@ -2742,13 +2732,12 @@ kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
mode_t mode, int flag)
{
struct nameidata nd;
cap_rights_t rights;
int error, follow;
AUDIT_ARG_MODE(mode);
follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
cap_rights_init(&rights, CAP_FCHMOD), td);
&cap_fchmod_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
@ -2770,13 +2759,12 @@ int
sys_fchmod(struct thread *td, struct fchmod_args *uap)
{
struct file *fp;
cap_rights_t rights;
int error;
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_MODE(uap->mode);
error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FCHMOD), &fp);
error = fget(td, uap->fd, &cap_fchmod_rights, &fp);
if (error != 0)
return (error);
error = fo_chmod(fp, uap->mode, td->td_ucred, td);
@ -2857,13 +2845,12 @@ kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
int uid, int gid, int flag)
{
struct nameidata nd;
cap_rights_t rights;
int error, follow;
AUDIT_ARG_OWNER(uid, gid);
follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
cap_rights_init(&rights, CAP_FCHOWN), td);
&cap_fchown_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@ -2905,12 +2892,11 @@ int
sys_fchown(struct thread *td, struct fchown_args *uap)
{
struct file *fp;
cap_rights_t rights;
int error;
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_OWNER(uap->uid, uap->gid);
error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FCHOWN), &fp);
error = fget(td, uap->fd, &cap_fchown_rights, &fp);
if (error != 0)
return (error);
error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td);
@ -3072,13 +3058,12 @@ kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
{
struct nameidata nd;
struct timespec ts[2];
cap_rights_t rights;
int error;
if ((error = getutimes(tptr, tptrseg, ts)) != 0)
return (error);
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd,
cap_rights_init(&rights, CAP_FUTIMES), td);
&cap_futimes_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@ -3146,14 +3131,13 @@ kern_futimes(struct thread *td, int fd, struct timeval *tptr,
{
struct timespec ts[2];
struct file *fp;
cap_rights_t rights;
int error;
AUDIT_ARG_FD(fd);
error = getutimes(tptr, tptrseg, ts);
if (error != 0)
return (error);
error = getvnode(td, fd, cap_rights_init(&rights, CAP_FUTIMES), &fp);
error = getvnode(td, fd, &cap_futimes_rights, &fp);
if (error != 0)
return (error);
#ifdef AUDIT
@ -3179,7 +3163,6 @@ kern_futimens(struct thread *td, int fd, struct timespec *tptr,
{
struct timespec ts[2];
struct file *fp;
cap_rights_t rights;
int error, flags;
AUDIT_ARG_FD(fd);
@ -3188,7 +3171,7 @@ kern_futimens(struct thread *td, int fd, struct timespec *tptr,
return (error);
if (flags & UTIMENS_EXIT)
return (0);
error = getvnode(td, fd, cap_rights_init(&rights, CAP_FUTIMES), &fp);
error = getvnode(td, fd, &cap_futimes_rights, &fp);
if (error != 0)
return (error);
#ifdef AUDIT
@ -3215,7 +3198,6 @@ kern_utimensat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
{
struct nameidata nd;
struct timespec ts[2];
cap_rights_t rights;
int error, flags;
if (flag & ~AT_SYMLINK_NOFOLLOW)
@ -3225,7 +3207,7 @@ kern_utimensat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
return (error);
NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW :
FOLLOW) | AUDITVNODE1, pathseg, path, fd,
cap_rights_init(&rights, CAP_FUTIMES), td);
&cap_futimes_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
/*
@ -3342,11 +3324,10 @@ kern_fsync(struct thread *td, int fd, bool fullsync)
struct vnode *vp;
struct mount *mp;
struct file *fp;
cap_rights_t rights;
int error, lock_flags;
AUDIT_ARG_FD(fd);
error = getvnode(td, fd, cap_rights_init(&rights, CAP_FSYNC), &fp);
error = getvnode(td, fd, &cap_fsync_rights, &fp);
if (error != 0)
return (error);
vp = fp->f_vnode;
@ -3441,7 +3422,6 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new,
struct mount *mp = NULL;
struct vnode *tvp, *fvp, *tdvp;
struct nameidata fromnd, tond;
cap_rights_t rights;
int error;
again:
@ -3449,11 +3429,11 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new,
#ifdef MAC
NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART |
AUDITVNODE1, pathseg, old, oldfd,
cap_rights_init(&rights, CAP_RENAMEAT_SOURCE), td);
&cap_renameat_source_rights, td);
#else
NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1,
pathseg, old, oldfd,
cap_rights_init(&rights, CAP_RENAMEAT_SOURCE), td);
&cap_renameat_source_rights, td);
#endif
if ((error = namei(&fromnd)) != 0)
@ -3468,7 +3448,7 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new,
fvp = fromnd.ni_vp;
NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE |
SAVESTART | AUDITVNODE2, pathseg, new, newfd,
cap_rights_init(&rights, CAP_RENAMEAT_TARGET), td);
&cap_renameat_target_rights, td);
if (fromnd.ni_vp->v_type == VDIR)
tond.ni_cnd.cn_flags |= WILLBEDIR;
if ((error = namei(&tond)) != 0) {
@ -3517,7 +3497,7 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new,
* from 'newfd'.
*/
error = cap_check(&tond.ni_filecaps.fc_rights,
cap_rights_init(&rights, CAP_UNLINKAT));
&cap_unlinkat_rights);
if (error != 0)
goto out;
}
@ -3605,14 +3585,13 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg,
struct vnode *vp;
struct vattr vattr;
struct nameidata nd;
cap_rights_t rights;
int error;
AUDIT_ARG_MODE(mode);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
NOCACHE, segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT),
NOCACHE, segflg, path, fd, &cap_mkdirat_rights,
td);
nd.ni_cnd.cn_flags |= WILLBEDIR;
if ((error = namei(&nd)) != 0)
@ -3681,13 +3660,12 @@ kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg)
struct mount *mp;
struct vnode *vp;
struct nameidata nd;
cap_rights_t rights;
int error;
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1,
pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td);
pathseg, path, fd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
vp = nd.ni_vp;

View File

@ -407,29 +407,44 @@ extern cap_rights_t cap_bind_rights;
extern cap_rights_t cap_connect_rights;
extern cap_rights_t cap_event_rights;
extern cap_rights_t cap_fchdir_rights;
extern cap_rights_t cap_fchflags_rights;
extern cap_rights_t cap_fchmod_rights;
extern cap_rights_t cap_fchown_rights;
extern cap_rights_t cap_fcntl_rights;
extern cap_rights_t cap_fexecve_rights;
extern cap_rights_t cap_flock_rights;
extern cap_rights_t cap_fpathconf_rights;
extern cap_rights_t cap_fstat_rights;
extern cap_rights_t cap_fstatfs_rights;
extern cap_rights_t cap_fsync_rights;
extern cap_rights_t cap_ftruncate_rights;
extern cap_rights_t cap_futimes_rights;
extern cap_rights_t cap_getpeername_rights;
extern cap_rights_t cap_getsockopt_rights;
extern cap_rights_t cap_getsockname_rights;
extern cap_rights_t cap_ioctl_rights;
extern cap_rights_t cap_linkat_source_rights;
extern cap_rights_t cap_linkat_target_rights;
extern cap_rights_t cap_listen_rights;
extern cap_rights_t cap_mkdirat_rights;
extern cap_rights_t cap_mkfifoat_rights;
extern cap_rights_t cap_mknodat_rights;
extern cap_rights_t cap_mmap_rights;
extern cap_rights_t cap_no_rights;
extern cap_rights_t cap_fsync_rights;
extern cap_rights_t cap_pdgetpid_rights;
extern cap_rights_t cap_pdkill_rights;
extern cap_rights_t cap_pread_rights;
extern cap_rights_t cap_pwrite_rights;
extern cap_rights_t cap_read_rights;
extern cap_rights_t cap_recv_rights;
extern cap_rights_t cap_renameat_source_rights;
extern cap_rights_t cap_renameat_target_rights;
extern cap_rights_t cap_seek_rights;
extern cap_rights_t cap_send_rights;
extern cap_rights_t cap_setsockopt_rights;
extern cap_rights_t cap_shutdown_rights;
extern cap_rights_t cap_symlinkat_rights;
extern cap_rights_t cap_unlinkat_rights;
extern cap_rights_t cap_write_rights;
#define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) != 0)