svn commit: r255219 - in head: contrib/tcpdump lib/libc lib/libc/capability lib/libc/include lib/libc/sys lib/libprocstat sbin/dhclient sbin/hastd sys/amd64/linux32 sys/bsm sys/cddl/compat/opensola...

Pawel Jakub Dawidek pjd at FreeBSD.org
Thu Sep 5 00:10:02 UTC 2013


Author: pjd
Date: Thu Sep  5 00:09:56 2013
New Revision: 255219
URL: http://svnweb.freebsd.org/changeset/base/255219

Log:
  Change the cap_rights_t type from uint64_t to a structure that we can extend
  in the future in a backward compatible (API and ABI) way.
  
  The cap_rights_t represents capability rights. We used to use one bit to
  represent one right, but we are running out of spare bits. Currently the new
  structure provides place for 114 rights (so 50 more than the previous
  cap_rights_t), but it is possible to grow the structure to hold at least 285
  rights, although we can make it even larger if 285 rights won't be enough.
  
  The structure definition looks like this:
  
  	struct cap_rights {
  		uint64_t	cr_rights[CAP_RIGHTS_VERSION + 2];
  	};
  
  The initial CAP_RIGHTS_VERSION is 0.
  
  The top two bits in the first element of the cr_rights[] array contain total
  number of elements in the array - 2. This means if those two bits are equal to
  0, we have 2 array elements.
  
  The top two bits in all remaining array elements should be 0.
  The next five bits in all array elements contain array index. Only one bit is
  used and bit position in this five-bits range defines array index. This means
  there can be at most five array elements in the future.
  
  To define new right the CAPRIGHT() macro must be used. The macro takes two
  arguments - an array index and a bit to set, eg.
  
  	#define	CAP_PDKILL	CAPRIGHT(1, 0x0000000000000800ULL)
  
  We still support aliases that combine few rights, but the rights have to belong
  to the same array element, eg:
  
  	#define	CAP_LOOKUP	CAPRIGHT(0, 0x0000000000000400ULL)
  	#define	CAP_FCHMOD	CAPRIGHT(0, 0x0000000000002000ULL)
  
  	#define	CAP_FCHMODAT	(CAP_FCHMOD | CAP_LOOKUP)
  
  There is new API to manage the new cap_rights_t structure:
  
  	cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
  	void cap_rights_set(cap_rights_t *rights, ...);
  	void cap_rights_clear(cap_rights_t *rights, ...);
  	bool cap_rights_is_set(const cap_rights_t *rights, ...);
  
  	bool cap_rights_is_valid(const cap_rights_t *rights);
  	void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
  	void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
  	bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
  
  Capability rights to the cap_rights_init(), cap_rights_set(),
  cap_rights_clear() and cap_rights_is_set() functions are provided by
  separating them with commas, eg:
  
  	cap_rights_t rights;
  
  	cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
  
  There is no need to terminate the list of rights, as those functions are
  actually macros that take care of the termination, eg:
  
  	#define	cap_rights_set(rights, ...)				\
  		__cap_rights_set((rights), __VA_ARGS__, 0ULL)
  	void __cap_rights_set(cap_rights_t *rights, ...);
  
  Thanks to using one bit as an array index we can assert in those functions that
  there are no two rights belonging to different array elements provided
  together. For example this is illegal and will be detected, because CAP_LOOKUP
  belongs to element 0 and CAP_PDKILL to element 1:
  
  	cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
  
  Providing several rights that belongs to the same array's element this way is
  correct, but is not advised. It should only be used for aliases definition.
  
  This commit also breaks compatibility with some existing Capsicum system calls,
  but I see no other way to do that. This should be fine as Capsicum is still
  experimental and this change is not going to 9.x.
  
  Sponsored by:	The FreeBSD Foundation

Added:
  head/lib/libc/capability/
  head/lib/libc/capability/Makefile.inc   (contents, props changed)
  head/lib/libc/capability/Symbol.map   (contents, props changed)
  head/sys/kern/subr_capability.c   (contents, props changed)
  head/sys/sys/caprights.h   (contents, props changed)
Modified:
  head/contrib/tcpdump/tcpdump.c
  head/lib/libc/Makefile
  head/lib/libc/include/compat.h
  head/lib/libc/sys/Symbol.map
  head/lib/libprocstat/libprocstat.c
  head/lib/libprocstat/libprocstat.h
  head/sbin/dhclient/bpf.c
  head/sbin/dhclient/dhclient.c
  head/sbin/hastd/subr.c
  head/sys/amd64/linux32/linux32_machdep.c
  head/sys/bsm/audit_kevents.h
  head/sys/bsm/audit_record.h
  head/sys/cddl/compat/opensolaris/sys/file.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c
  head/sys/compat/freebsd32/freebsd32_capability.c
  head/sys/compat/freebsd32/freebsd32_ioctl.c
  head/sys/compat/freebsd32/freebsd32_misc.c
  head/sys/compat/freebsd32/syscalls.master
  head/sys/compat/linux/linux_file.c
  head/sys/compat/linux/linux_ioctl.c
  head/sys/compat/linux/linux_socket.c
  head/sys/compat/svr4/svr4_fcntl.c
  head/sys/compat/svr4/svr4_filio.c
  head/sys/compat/svr4/svr4_ioctl.c
  head/sys/compat/svr4/svr4_misc.c
  head/sys/compat/svr4/svr4_stream.c
  head/sys/conf/files
  head/sys/dev/aac/aac_linux.c
  head/sys/dev/amr/amr_linux.c
  head/sys/dev/filemon/filemon.c
  head/sys/dev/hwpmc/hwpmc_logging.c
  head/sys/dev/ipmi/ipmi_linux.c
  head/sys/dev/iscsi_initiator/iscsi.c
  head/sys/dev/mfi/mfi_linux.c
  head/sys/dev/tdfx/tdfx_linux.c
  head/sys/fs/fdescfs/fdesc_vnops.c
  head/sys/fs/fuse/fuse_vfsops.c
  head/sys/fs/nfsclient/nfs_clport.c
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/i386/ibcs2/ibcs2_fcntl.c
  head/sys/i386/ibcs2/ibcs2_ioctl.c
  head/sys/i386/ibcs2/ibcs2_misc.c
  head/sys/i386/linux/linux_machdep.c
  head/sys/kern/capabilities.conf
  head/sys/kern/kern_descrip.c
  head/sys/kern/kern_event.c
  head/sys/kern/kern_exec.c
  head/sys/kern/kern_ktrace.c
  head/sys/kern/kern_sig.c
  head/sys/kern/sys_capability.c
  head/sys/kern/sys_generic.c
  head/sys/kern/sys_procdesc.c
  head/sys/kern/syscalls.master
  head/sys/kern/tty.c
  head/sys/kern/uipc_mqueue.c
  head/sys/kern/uipc_sem.c
  head/sys/kern/uipc_syscalls.c
  head/sys/kern/uipc_usrreq.c
  head/sys/kern/vfs_acl.c
  head/sys/kern/vfs_aio.c
  head/sys/kern/vfs_extattr.c
  head/sys/kern/vfs_lookup.c
  head/sys/kern/vfs_syscalls.c
  head/sys/netsmb/smb_dev.c
  head/sys/nfsserver/nfs_srvkrpc.c
  head/sys/security/audit/audit.h
  head/sys/security/audit/audit_arg.c
  head/sys/security/audit/audit_bsm.c
  head/sys/security/audit/audit_private.h
  head/sys/security/audit/bsm_token.c
  head/sys/security/mac/mac_syscalls.c
  head/sys/sys/_types.h
  head/sys/sys/capability.h
  head/sys/sys/file.h
  head/sys/sys/filedesc.h
  head/sys/sys/ktrace.h
  head/sys/sys/namei.h
  head/sys/sys/procdesc.h
  head/sys/sys/types.h
  head/sys/sys/user.h
  head/sys/ufs/ffs/ffs_alloc.c
  head/sys/vm/vm_mmap.c
  head/usr.bin/kdump/kdump.c
  head/usr.bin/kdump/mksubr
  head/usr.bin/procstat/procstat_files.c
  head/usr.bin/rwho/rwho.c
  head/usr.bin/uniq/uniq.c
  head/usr.sbin/rwhod/rwhod.c

Modified: head/contrib/tcpdump/tcpdump.c
==============================================================================
--- head/contrib/tcpdump/tcpdump.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/contrib/tcpdump/tcpdump.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -715,8 +715,9 @@ main(int argc, char **argv)
 	int status;
 	FILE *VFile;
 #ifdef __FreeBSD__
+	cap_rights_t rights;
 	int cansandbox;
-#endif
+#endif	/* __FreeBSD__ */
 
 #ifdef WIN32
 	if(wsockinit() != 0) return 1;
@@ -1206,7 +1207,8 @@ main(int argc, char **argv)
 		if (pd == NULL)
 			error("%s", ebuf);
 #ifdef __FreeBSD__
-		if (cap_rights_limit(fileno(pcap_file(pd)), CAP_READ) < 0 &&
+		cap_rights_init(&rights, CAP_READ);
+		if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
 		    errno != ENOSYS) {
 			error("unable to limit pcap descriptor");
 		}
@@ -1484,8 +1486,9 @@ main(int argc, char **argv)
 	if (RFileName == NULL && VFileName == NULL) {
 		static const unsigned long cmds[] = { BIOCGSTATS };
 
-		if (cap_rights_limit(pcap_fileno(pd),
-		    CAP_IOCTL | CAP_READ) < 0 && errno != ENOSYS) {
+		cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
+		if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
+		    errno != ENOSYS) {
 			error("unable to limit pcap descriptor");
 		}
 		if (cap_ioctls_limit(pcap_fileno(pd), cmds,
@@ -1516,8 +1519,9 @@ main(int argc, char **argv)
 		if (p == NULL)
 			error("%s", pcap_geterr(pd));
 #ifdef __FreeBSD__
-		if (cap_rights_limit(fileno(pcap_dump_file(p)),
-		    CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) {
+		cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
+		if (cap_rights_limit(fileno(pcap_dump_file(p)), &rights) < 0 &&
+		    errno != ENOSYS) {
 			error("unable to limit dump descriptor");
 		}
 #endif
@@ -1530,9 +1534,10 @@ main(int argc, char **argv)
 				error("unable to open directory %s",
 				    dirname(WFileName));
 			}
-			if (cap_rights_limit(dumpinfo.dirfd, CAP_CREATE |
-			    CAP_FCNTL | CAP_FTRUNCATE | CAP_LOOKUP | CAP_SEEK |
-			    CAP_WRITE) < 0 && errno != ENOSYS) {
+			cap_rights_init(&rights, CAP_CREATE, CAP_FCNTL,
+			    CAP_FTRUNCATE, CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
+			if (cap_rights_limit(dumpinfo.dirfd, &rights) < 0 &&
+			    errno != ENOSYS) {
 				error("unable to limit directory rights");
 			}
 #else	/* !__FreeBSD__ */
@@ -1615,7 +1620,7 @@ main(int argc, char **argv)
 		error("unable to enter the capability mode");
 	if (cap_sandboxed())
 		fprintf(stderr, "capability mode sandbox enabled\n");
-#endif
+#endif	/* __FreeBSD__ */
 
 	do {
 		status = pcap_loop(pd, cnt, callback, pcap_userdata);
@@ -1657,8 +1662,9 @@ main(int argc, char **argv)
 				if (pd == NULL)
 					error("%s", ebuf);
 #ifdef __FreeBSD__
+				cap_rights_init(&rights, CAP_READ);
 				if (cap_rights_limit(fileno(pcap_file(pd)),
-				    CAP_READ) < 0 && errno != ENOSYS) {
+				    &rights) < 0 && errno != ENOSYS) {
 					error("unable to limit pcap descriptor");
 				}
 #endif
@@ -1830,6 +1836,9 @@ static void
 dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
 {
 	struct dump_info *dump_info;
+#ifdef __FreeBSD__
+	cap_rights_t rights;
+#endif
 
 	++packets_captured;
 
@@ -1933,8 +1942,9 @@ dump_packet_and_trunc(u_char *user, cons
 			if (dump_info->p == NULL)
 				error("%s", pcap_geterr(pd));
 #ifdef __FreeBSD__
+			cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
 			if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)),
-			    CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) {
+			    &rights) < 0 && errno != ENOSYS) {
 				error("unable to limit dump descriptor");
 			}
 #endif
@@ -1993,8 +2003,9 @@ dump_packet_and_trunc(u_char *user, cons
 		if (dump_info->p == NULL)
 			error("%s", pcap_geterr(pd));
 #ifdef __FreeBSD__
+		cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
 		if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)),
-		    CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) {
+		    &rights) < 0 && errno != ENOSYS) {
 			error("unable to limit dump descriptor");
 		}
 #endif

Modified: head/lib/libc/Makefile
==============================================================================
--- head/lib/libc/Makefile	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/lib/libc/Makefile	Thu Sep  5 00:09:56 2013	(r255219)
@@ -100,6 +100,7 @@ NOASM=
 CFLAGS+= -DYP
 .include "${.CURDIR}/yp/Makefile.inc"
 .endif
+.include "${.CURDIR}/capability/Makefile.inc"
 .if ${MK_HESIOD} != "no"
 CFLAGS+= -DHESIOD
 .endif

Added: head/lib/libc/capability/Makefile.inc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/capability/Makefile.inc	Thu Sep  5 00:09:56 2013	(r255219)
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+# capability sources
+.PATH: ${.CURDIR}/../../sys/kern
+
+SRCS+=	subr_capability.c
+
+SYM_MAPS+=	${.CURDIR}/capability/Symbol.map
+
+#MAN+=	cap_rights_init.3
+
+#MLINKS+=cap_rights_init.3 cap_rights_set.3
+#MLINKS+=cap_rights_init.3 cap_rights_clear.3
+#MLINKS+=cap_rights_init.3 cap_rights_is_set.3
+#MLINKS+=cap_rights_init.3 cap_rights_is_valid.3
+#MLINKS+=cap_rights_init.3 cap_rights_merge.3
+#MLINKS+=cap_rights_init.3 cap_rights_remove.3
+#MLINKS+=cap_rights_init.3 cap_rights_contains.3
+

Added: head/lib/libc/capability/Symbol.map
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/capability/Symbol.map	Thu Sep  5 00:09:56 2013	(r255219)
@@ -0,0 +1,14 @@
+/*
+ * $FreeBSD$
+ */
+
+FBSD_1.3 {
+	__cap_rights_clear;
+	cap_rights_contains;
+	__cap_rights_init;
+	__cap_rights_is_set;
+	cap_rights_is_valid;
+	cap_rights_merge;
+	cap_rights_remove;
+	__cap_rights_set;
+};

Modified: head/lib/libc/include/compat.h
==============================================================================
--- head/lib/libc/include/compat.h	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/lib/libc/include/compat.h	Thu Sep  5 00:09:56 2013	(r255219)
@@ -42,8 +42,6 @@ __sym_compat(__semctl, freebsd7___semctl
 __sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0);
 __sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0);
 
-__sym_compat(cap_getrights, cap_rights_get, FBSD_1.2);
-
 #undef __sym_compat
 
 #endif	/* __LIBC_COMPAT_H__ */

Modified: head/lib/libc/sys/Symbol.map
==============================================================================
--- head/lib/libc/sys/Symbol.map	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/lib/libc/sys/Symbol.map	Thu Sep  5 00:09:56 2013	(r255219)
@@ -363,7 +363,6 @@ FBSD_1.1 {
 FBSD_1.2 {
 	cap_enter;
 	cap_getmode;
-	cap_new;
 	getloginclass;
 	pdfork;
 	pdgetpid;
@@ -385,7 +384,7 @@ FBSD_1.3 {
 	cap_fcntls_limit;
 	cap_ioctls_get;
 	cap_ioctls_limit;
-	cap_rights_get;
+	__cap_rights_get;
 	cap_rights_limit;
 	cap_sandboxed;
 	chflagsat;

Modified: head/lib/libprocstat/libprocstat.c
==============================================================================
--- head/lib/libprocstat/libprocstat.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/lib/libprocstat/libprocstat.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -378,7 +378,7 @@ procstat_freefiles(struct procstat *proc
 
 static struct filestat *
 filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags,
-    int refcount, off_t offset, char *path, cap_rights_t cap_rights)
+    int refcount, off_t offset, char *path, cap_rights_t *cap_rightsp)
 {
 	struct filestat *entry;
 
@@ -395,7 +395,7 @@ filestat_new_entry(void *typedep, int ty
 	entry->fs_ref_count = refcount;
 	entry->fs_offset = offset;
 	entry->fs_path = path;
-	entry->fs_cap_rights = cap_rights;
+	entry->fs_cap_rights = *cap_rightsp;
 	return (entry);
 }
 
@@ -851,7 +851,7 @@ procstat_getfiles_sysctl(struct procstat
 		 * Create filestat entry.
 		 */
 		entry = filestat_new_entry(kif, type, fd, fflags, uflags,
-		    refcount, offset, path, cap_rights);
+		    refcount, offset, path, &cap_rights);
 		if (entry != NULL)
 			STAILQ_INSERT_TAIL(head, entry, next);
 	}

Modified: head/lib/libprocstat/libprocstat.h
==============================================================================
--- head/lib/libprocstat/libprocstat.h	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/lib/libprocstat/libprocstat.h	Thu Sep  5 00:09:56 2013	(r255219)
@@ -36,6 +36,7 @@
 #ifndef ZFS
 #include <sys/elf.h>
 #endif
+#include <sys/caprights.h>
 
 /*
  * Vnode types.

Modified: head/sbin/dhclient/bpf.c
==============================================================================
--- head/sbin/dhclient/bpf.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sbin/dhclient/bpf.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -43,6 +43,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/capability.h>
+
 #include "dhcpd.h"
 #include "privsep.h"
 #include <sys/capability.h>
@@ -132,6 +134,7 @@ int dhcp_bpf_wfilter_len = sizeof(dhcp_b
 void
 if_register_send(struct interface_info *info)
 {
+	cap_rights_t rights;
 	struct bpf_version v;
 	struct bpf_program p;
 	int sock, on = 1;
@@ -160,7 +163,8 @@ if_register_send(struct interface_info *
 	if (ioctl(info->wfdesc, BIOCLOCK, NULL) < 0)
 		error("Cannot lock bpf");
 
-	if (cap_rights_limit(info->wfdesc, CAP_WRITE) < 0 && errno != ENOSYS)
+	cap_rights_init(&rights, CAP_WRITE);
+	if (cap_rights_limit(info->wfdesc, &rights) < 0 && errno != ENOSYS)
 		error("Can't limit bpf descriptor: %m");
 
 	/*
@@ -213,6 +217,7 @@ void
 if_register_receive(struct interface_info *info)
 {
 	static const unsigned long cmds[2] = { SIOCGIFFLAGS, SIOCGIFMEDIA };
+	cap_rights_t rights;
 	struct bpf_version v;
 	struct bpf_program p;
 	int flag = 1, sz;
@@ -264,10 +269,9 @@ if_register_receive(struct interface_inf
 	if (ioctl(info->rfdesc, BIOCLOCK, NULL) < 0)
 		error("Cannot lock bpf");
 
-	if (cap_rights_limit(info->rfdesc,
-	    CAP_IOCTL | CAP_POLL_EVENT | CAP_READ) < 0 && errno != ENOSYS) {
+	cap_rights_init(&rights, CAP_IOCTL, CAP_POLL_EVENT, CAP_READ);
+	if (cap_rights_limit(info->rfdesc, &rights) < 0 && errno != ENOSYS)
 		error("Can't limit bpf descriptor: %m");
-	}
 	if (cap_ioctls_limit(info->rfdesc, cmds, 2) < 0 && errno != ENOSYS)
 		error("Can't limit ioctls for bpf descriptor: %m");
 }

Modified: head/sbin/dhclient/dhclient.c
==============================================================================
--- head/sbin/dhclient/dhclient.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sbin/dhclient/dhclient.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -56,6 +56,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/capability.h>
+
 #include "dhcpd.h"
 #include "privsep.h"
 
@@ -346,6 +348,7 @@ main(int argc, char *argv[])
 	int			 immediate_daemon = 0;
 	struct passwd		*pw;
 	pid_t			 otherpid;
+	cap_rights_t		 rights;
 
 	/* Initially, log errors to stderr as well as to syslogd. */
 	openlog(__progname, LOG_PID | LOG_NDELAY, DHCPD_LOG_FACILITY);
@@ -477,10 +480,9 @@ main(int argc, char *argv[])
 
 	close(pipe_fd[0]);
 	privfd = pipe_fd[1];
-	if (cap_rights_limit(privfd, CAP_READ | CAP_WRITE) < 0 &&
-	    errno != ENOSYS) {
+	cap_rights_init(&rights, CAP_READ, CAP_WRITE);
+	if (cap_rights_limit(privfd, &rights) < 0 && errno != ENOSYS)
 		error("can't limit private descriptor: %m");
-	}
 
 	if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1)
 		error("can't open and lock %s: %m", path_dhclient_db);
@@ -492,10 +494,9 @@ main(int argc, char *argv[])
 		add_protocol("AF_ROUTE", routefd, routehandler, ifi);
 	if (shutdown(routefd, SHUT_WR) < 0)
 		error("can't shutdown route socket: %m");
-	if (cap_rights_limit(routefd, CAP_POLL_EVENT | CAP_READ) < 0 &&
-	    errno != ENOSYS) {
+	cap_rights_init(&rights, CAP_POLL_EVENT, CAP_READ);
+	if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
 		error("can't limit route socket: %m");
-	}
 
 	if (chroot(_PATH_VAREMPTY) == -1)
 		error("chroot");
@@ -1840,13 +1841,15 @@ void
 rewrite_client_leases(void)
 {
 	struct client_lease *lp;
+	cap_rights_t rights;
 
 	if (!leaseFile) {
 		leaseFile = fopen(path_dhclient_db, "w");
 		if (!leaseFile)
 			error("can't create %s: %m", path_dhclient_db);
-		if (cap_rights_limit(fileno(leaseFile), CAP_FSTAT | CAP_FSYNC |
-		    CAP_FTRUNCATE | CAP_SEEK | CAP_WRITE) < 0 &&
+		cap_rights_init(&rights, CAP_FSTAT, CAP_FSYNC, CAP_FTRUNCATE,
+		    CAP_SEEK, CAP_WRITE);
+		if (cap_rights_limit(fileno(leaseFile), &rights) < 0 &&
 		    errno != ENOSYS) {
 			error("can't limit lease descriptor: %m");
 		}
@@ -2354,6 +2357,7 @@ void
 go_daemon(void)
 {
 	static int state = 0;
+	cap_rights_t rights;
 
 	if (no_daemon || state)
 		return;
@@ -2366,9 +2370,11 @@ go_daemon(void)
 	if (daemon(1, 0) == -1)
 		error("daemon");
 
+	cap_rights_init(&rights);
+
 	if (pidfile != NULL) {
 		pidfile_write(pidfile);
-		if (cap_rights_limit(pidfile_fileno(pidfile), CAP_NONE) < 0 &&
+		if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
 		    errno != ENOSYS) {
 			error("can't limit pidfile descriptor: %m");
 		}
@@ -2383,11 +2389,12 @@ go_daemon(void)
 		nullfd = -1;
 	}
 
-	if (cap_rights_limit(STDIN_FILENO, CAP_NONE) < 0 && errno != ENOSYS)
+	if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
 		error("can't limit stdin: %m");
-	if (cap_rights_limit(STDOUT_FILENO, CAP_WRITE) < 0 && errno != ENOSYS)
+	cap_rights_init(&rights, CAP_WRITE);
+	if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
 		error("can't limit stdout: %m");
-	if (cap_rights_limit(STDERR_FILENO, CAP_WRITE) < 0 && errno != ENOSYS)
+	if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
 		error("can't limit stderr: %m");
 }
 

Modified: head/sbin/hastd/subr.c
==============================================================================
--- head/sbin/hastd/subr.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sbin/hastd/subr.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -231,6 +231,7 @@ drop_privs(const struct hast_resource *r
 		pjdlog_common(LOG_DEBUG, 1, errno,
 		    "Unable to sandbox using capsicum");
 	} else if (res != NULL) {
+		cap_rights_t rights;
 		static const unsigned long geomcmds[] = {
 		    DIOCGDELETE,
 		    DIOCGFLUSH
@@ -239,8 +240,9 @@ drop_privs(const struct hast_resource *r
 		PJDLOG_ASSERT(res->hr_role == HAST_ROLE_PRIMARY ||
 		    res->hr_role == HAST_ROLE_SECONDARY);
 
-		if (cap_rights_limit(res->hr_localfd,
-		    CAP_FLOCK | CAP_IOCTL | CAP_PREAD | CAP_PWRITE) == -1) {
+		cap_rights_init(&rights, CAP_FLOCK, CAP_IOCTL, CAP_PREAD,
+		    CAP_PWRITE);
+		if (cap_rights_limit(res->hr_localfd, &rights) == -1) {
 			pjdlog_errno(LOG_ERR,
 			    "Unable to limit capability rights on local descriptor");
 		}
@@ -258,7 +260,8 @@ drop_privs(const struct hast_resource *r
 			    G_GATE_CMD_DESTROY
 			};
 
-			if (cap_rights_limit(res->hr_ggatefd, CAP_IOCTL) == -1) {
+			cap_rights_init(&rights, CAP_IOCTL);
+			if (cap_rights_limit(res->hr_ggatefd, &rights) == -1) {
 				pjdlog_errno(LOG_ERR,
 				    "Unable to limit capability rights to CAP_IOCTL on ggate descriptor");
 			}

Modified: head/sys/amd64/linux32/linux32_machdep.c
==============================================================================
--- head/sys/amd64/linux32/linux32_machdep.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/amd64/linux32/linux32_machdep.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -519,6 +519,7 @@ linux_mmap_common(struct thread *td, l_u
 	} */ bsd_args;
 	int error;
 	struct file *fp;
+	cap_rights_t rights;
 
 	error = 0;
 	bsd_args.flags = 0;
@@ -567,7 +568,9 @@ linux_mmap_common(struct thread *td, l_u
 		 * protection options specified.
 		 */
 
-		if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0)
+		error = fget(td, bsd_args.fd,
+		    cap_rights_init(&rights, CAP_MMAP), &fp);
+		if (error != 0)
 			return (error);
 		if (fp->f_type != DTYPE_VNODE) {
 			fdrop(fp, td);

Modified: head/sys/bsm/audit_kevents.h
==============================================================================
--- head/sys/bsm/audit_kevents.h	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/bsm/audit_kevents.h	Thu Sep  5 00:09:56 2013	(r255219)
@@ -589,6 +589,7 @@
 #define	AUE_POSIX_OPENPT	43185	/* FreeBSD. */
 #define	AUE_CAP_NEW		43186	/* TrustedBSD. */
 #define	AUE_CAP_RIGHTS_GET	43187	/* TrustedBSD. */
+#define	AUE_CAP_GETRIGHTS	AUE_CAP_RIGHTS_GET
 #define	AUE_CAP_ENTER		43188	/* TrustedBSD. */
 #define	AUE_CAP_GETMODE		43189	/* TrustedBSD. */
 #define	AUE_POSIX_SPAWN		43190	/* Darwin. */

Modified: head/sys/bsm/audit_record.h
==============================================================================
--- head/sys/bsm/audit_record.h	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/bsm/audit_record.h	Thu Sep  5 00:09:56 2013	(r255219)
@@ -34,6 +34,7 @@
 #define _BSM_AUDIT_RECORD_H_
 
 #include <sys/time.h>			/* struct timeval */
+#include <sys/caprights.h>		/* cap_rights_t */
 
 /*
  * Token type identifiers.
@@ -126,6 +127,8 @@
 #define	AUT_SOCKINET128		0x81		/* XXX */
 #define	AUT_SOCKUNIX		0x82		/* XXX */
 
+#define	AUT_RIGHTS		0x83
+
 /* print values for the arbitrary token */
 #define AUP_BINARY      0
 #define AUP_OCTAL       1
@@ -248,6 +251,7 @@ token_t	*au_to_process32_ex(au_id_t auid
 	    au_tid_addr_t *tid);
 token_t	*au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
 	    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid);
+token_t	*au_to_rights(cap_rights_t *rightsp);
 token_t	*au_to_return(char status, uint32_t ret);
 token_t	*au_to_return32(char status, uint32_t ret);
 token_t	*au_to_return64(char status, uint64_t ret);

Modified: head/sys/cddl/compat/opensolaris/sys/file.h
==============================================================================
--- head/sys/cddl/compat/opensolaris/sys/file.h	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/cddl/compat/opensolaris/sys/file.h	Thu Sep  5 00:09:56 2013	(r255219)
@@ -39,11 +39,11 @@ typedef	struct file	file_t;
 #include <sys/capability.h>
 
 static __inline file_t *
-getf(int fd, cap_rights_t rights)
+getf(int fd, cap_rights_t *rightsp)
 {
 	struct file *fp;
 
-	if (fget(curthread, fd, rights, &fp) == 0)
+	if (fget(curthread, fd, rightsp, &fp) == 0)
 		return (fp);
 	return (NULL);
 }

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -4005,6 +4005,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
 	char *origin = NULL;
 	char *tosnap;
 	char tofs[ZFS_MAXNAMELEN];
+	cap_rights_t rights;
 	boolean_t first_recvd_props = B_FALSE;
 
 	if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
@@ -4022,7 +4023,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
 		return (error);
 
 	fd = zc->zc_cookie;
-	fp = getf(fd, CAP_PREAD);
+	fp = getf(fd, cap_rights_init(&rights, CAP_PREAD));
 	if (fp == NULL) {
 		nvlist_free(props);
 		return (SET_ERROR(EBADF));
@@ -4260,7 +4261,11 @@ zfs_ioc_send(zfs_cmd_t *zc)
 		dsl_dataset_rele(tosnap, FTAG);
 		dsl_pool_rele(dp, FTAG);
 	} else {
-		file_t *fp = getf(zc->zc_cookie, CAP_WRITE);
+		file_t *fp;
+		cap_rights_t rights;
+
+		fp = getf(zc->zc_cookie,
+		    cap_rights_init(&rights, CAP_WRITE));
 		if (fp == NULL)
 			return (SET_ERROR(EBADF));
 
@@ -4851,10 +4856,11 @@ static int
 zfs_ioc_diff(zfs_cmd_t *zc)
 {
 	file_t *fp;
+	cap_rights_t rights;
 	offset_t off;
 	int error;
 
-	fp = getf(zc->zc_cookie, CAP_WRITE);
+	fp = getf(zc->zc_cookie, cap_rights_init(&rights, CAP_WRITE));
 	if (fp == NULL)
 		return (SET_ERROR(EBADF));
 
@@ -5214,6 +5220,7 @@ zfs_ioc_unjail(zfs_cmd_t *zc)
 static int
 zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
 {
+	cap_rights_t rights;
 	int error;
 	offset_t off;
 	char *fromname = NULL;
@@ -5225,7 +5232,7 @@ zfs_ioc_send_new(const char *snapname, n
 
 	(void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
 
-	file_t *fp = getf(fd, CAP_READ);
+	file_t *fp = getf(fd, cap_rights_init(&rights, CAP_READ));
 	if (fp == NULL)
 		return (SET_ERROR(EBADF));
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -122,10 +122,11 @@ zfs_onexit_fd_hold(int fd, minor_t *mino
 {
 	file_t *fp, *tmpfp;
 	zfs_onexit_t *zo;
+	cap_rights_t rights;
 	void *data;
 	int error;
 
-	fp = getf(fd, CAP_NONE);
+	fp = getf(fd, cap_rights_init(&rights));
 	if (fp == NULL)
 		return (SET_ERROR(EBADF));
 

Modified: head/sys/compat/freebsd32/freebsd32_capability.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_capability.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/compat/freebsd32/freebsd32_capability.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
 
 #include <security/audit/audit.h>
 
-#include <compat/freebsd32/freebsd32_misc.h>
 #include <compat/freebsd32/freebsd32_proto.h>
 
 #ifdef CAPABILITIES
@@ -50,17 +49,6 @@ __FBSDID("$FreeBSD$");
 MALLOC_DECLARE(M_FILECAPS);
 
 int
-freebsd32_cap_rights_limit(struct thread *td,
-    struct freebsd32_cap_rights_limit_args *uap)
-{
-	struct cap_rights_limit_args ap;
-
-	ap.fd = uap->fd;
-	ap.rights = PAIR32TO64(uint64_t, uap->rights);
-	return (sys_cap_rights_limit(td, &ap));
-}
-
-int
 freebsd32_cap_ioctls_limit(struct thread *td,
     struct freebsd32_cap_ioctls_limit_args *uap)
 {
@@ -148,14 +136,6 @@ out:
 #else /* !CAPABILITIES */
 
 int
-freebsd32_cap_rights_limit(struct thread *td,
-    struct freebsd32_cap_rights_limit_args *uap)
-{
-
-	return (ENOSYS);
-}
-
-int
 freebsd32_cap_ioctls_limit(struct thread *td,
     struct freebsd32_cap_ioctls_limit_args *uap)
 {

Modified: head/sys/compat/freebsd32/freebsd32_ioctl.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_ioctl.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/compat/freebsd32/freebsd32_ioctl.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -353,9 +353,11 @@ freebsd32_ioctl(struct thread *td, struc
 		caddr_t	data;
 	}*/ ;
 	struct file *fp;
+	cap_rights_t rights;
 	int error;
 
-	if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
 		fdrop(fp, td);

Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/compat/freebsd32/freebsd32_misc.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -1650,6 +1650,7 @@ freebsd32_do_sendfile(struct thread *td,
 	struct uio *hdr_uio, *trl_uio;
 	struct iovec32 *iov32;
 	struct file *fp;
+	cap_rights_t rights;
 	off_t offset;
 	int error;
 
@@ -1686,8 +1687,10 @@ freebsd32_do_sendfile(struct thread *td,
 
 	AUDIT_ARG_FD(uap->fd);
 
-	if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0)
+	if ((error = fget_read(td, uap->fd,
+	    cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) {
 		goto out;
+	}
 
 	error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset,
 	    uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td);

Modified: head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- head/sys/compat/freebsd32/syscalls.master	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/compat/freebsd32/syscalls.master	Thu Sep  5 00:09:56 2013	(r255219)
@@ -970,9 +970,9 @@
 512	AUE_SHMCTL	NOSTD	{ int freebsd32_shmctl(int shmid, int cmd, \
 				    struct shmid_ds32 *buf); }
 513	AUE_LPATHCONF	NOPROTO	{ int lpathconf(char *path, int name); }
-514	AUE_CAP_NEW	NOPROTO	{ int cap_new(int fd, uint64_t rights); }
-515	AUE_CAP_RIGHTS_GET	NOPROTO	{ int cap_rights_get(int fd, \
-				    uint64_t *rightsp); }
+514	AUE_NULL	OBSOL	cap_new
+515	AUE_CAP_RIGHTS_GET	NOPROTO	{ int __cap_rights_get(int version, \
+				    int fd, cap_rights_t *rightsp); }
 516	AUE_CAP_ENTER	NOPROTO	{ int cap_enter(void); }
 517	AUE_CAP_GETMODE	NOPROTO	{ int cap_getmode(u_int *modep); }
 518	AUE_PDFORK	NOPROTO	{ int pdfork(int *fdp, int flags); }
@@ -1016,10 +1016,6 @@
 				    int *status, int options, \
 				    struct wrusage32 *wrusage, \
 				    siginfo_t *info); }
-533	AUE_CAP_RIGHTS_LIMIT	STD	{ \
-				    int freebsd32_cap_rights_limit(int fd, \
-				    int pad, \
-				    uint32_t rights1, uint32_t rights2); }
 #else
 530	AUE_NULL	STD	{ int freebsd32_posix_fallocate(int fd,\
 				    uint32_t offset1, uint32_t offset2,\
@@ -1033,10 +1029,10 @@
 				    int *status, int options, \
 				    struct wrusage32 *wrusage, \
 				    siginfo_t *info); }
-533	AUE_CAP_RIGHTS_LIMIT	STD	{ \
-				    int freebsd32_cap_rights_limit(int fd, \
-				    uint32_t rights1, uint32_t rights2); }
 #endif
+533	AUE_CAP_RIGHTS_LIMIT	NOPROTO	{ \
+				    int cap_rights_limit(int fd, \
+				    cap_rights_t *rightsp); }
 534	AUE_CAP_IOCTLS_LIMIT	STD	{ \
 				    int freebsd32_cap_ioctls_limit(int fd, \
 				    const uint32_t *cmds, size_t ncmds); }

Modified: head/sys/compat/linux/linux_file.c
==============================================================================
--- head/sys/compat/linux/linux_file.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/compat/linux/linux_file.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -92,6 +92,7 @@ linux_creat(struct thread *td, struct li
 static int
 linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode)
 {
+    cap_rights_t rights;
     struct proc *p = td->td_proc;
     struct file *fp;
     int fd;
@@ -143,7 +144,7 @@ linux_common_open(struct thread *td, int
 	     * having the same filedesc could use that fd without
 	     * checking below.
 	     */
-	    error = fget(td, fd, CAP_IOCTL, &fp);
+	    error = fget(td, fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
 	    if (!error) {
 		    sx_slock(&proctree_lock);
 		    PROC_LOCK(p);
@@ -328,6 +329,7 @@ getdents_common(struct thread *td, struc
 	caddr_t outp;			/* Linux-format */
 	int resid, linuxreclen=0;	/* Linux-format */
 	caddr_t lbuf;			/* Linux-format */
+	cap_rights_t rights;
 	struct file *fp;
 	struct uio auio;
 	struct iovec aiov;
@@ -348,7 +350,9 @@ getdents_common(struct thread *td, struc
 	} else
 		justone = 0;
 
-	if ((error = getvnode(td->td_proc->p_fd, args->fd, CAP_READ, &fp)) != 0)
+	error = getvnode(td->td_proc->p_fd, args->fd,
+	    cap_rights_init(&rights, CAP_READ), &fp);
+	if (error != 0)
 		return (error);
 
 	if ((fp->f_flag & FREAD) == 0) {
@@ -1024,6 +1028,7 @@ linux_pread(td, uap)
 	struct linux_pread_args *uap;
 {
 	struct pread_args bsd;
+	cap_rights_t rights;
 	struct vnode *vp;
 	int error;
 
@@ -1036,7 +1041,9 @@ linux_pread(td, uap)
 
 	if (error == 0) {
 		/* This seems to violate POSIX but linux does it */
-		if ((error = fgetvp(td, uap->fd, CAP_PREAD, &vp)) != 0)
+		error = fgetvp(td, uap->fd,
+		    cap_rights_init(&rights, CAP_PREAD), &vp);
+		if (error != 0)
 			return (error);
 		if (vp->v_type == VDIR) {
 			vrele(vp);
@@ -1283,6 +1290,7 @@ fcntl_common(struct thread *td, struct l
 {
 	struct l_flock linux_flock;
 	struct flock bsd_flock;
+	cap_rights_t rights;
 	struct file *fp;
 	long arg;
 	int error, result;
@@ -1385,7 +1393,8 @@ fcntl_common(struct thread *td, struct l
 		 * significant effect for pipes (SIGIO is not delivered for
 		 * pipes under Linux-2.2.35 at least).
 		 */
-		error = fget(td, args->fd, CAP_FCNTL, &fp);
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_FCNTL), &fp);
 		if (error)
 			return (error);
 		if (fp->f_type == DTYPE_PIPE) {

Modified: head/sys/compat/linux/linux_ioctl.c
==============================================================================
--- head/sys/compat/linux/linux_ioctl.c	Wed Sep  4 23:32:49 2013	(r255218)
+++ head/sys/compat/linux/linux_ioctl.c	Thu Sep  5 00:09:56 2013	(r255219)
@@ -189,12 +189,14 @@ struct linux_hd_big_geometry {
 static int
 linux_ioctl_hdio(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 	u_int sectorsize, fwcylinders, fwheads, fwsectors;
 	off_t mediasize, bytespercyl;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 	case LINUX_HDIO_GET_GEO:
@@ -270,12 +272,14 @@ linux_ioctl_hdio(struct thread *td, stru
 static int
 linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 	u_int sectorsize;
 	off_t mediasize;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 	case LINUX_BLKGETSIZE:
@@ -698,10 +702,12 @@ linux_ioctl_termio(struct thread *td, st
 	struct termios bios;
 	struct linux_termios lios;
 	struct linux_termio lio;
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 
 	switch (args->cmd & 0xffff) {
@@ -1438,10 +1444,12 @@ bsd_to_linux_dvd_authinfo(struct dvd_aut
 static int
 linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 
@@ -1963,10 +1971,12 @@ linux_ioctl_sound(struct thread *td, str
 static int
 linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 
@@ -2351,6 +2361,7 @@ static int
 linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args)
 {
 	char lifname[LINUX_IFNAMSIZ], ifname[IFNAMSIZ];
+	cap_rights_t rights;
 	struct ifnet *ifp;
 	struct file *fp;
 	int error, type;
@@ -2358,7 +2369,8 @@ linux_ioctl_socket(struct thread *td, st
 	ifp = NULL;
 	error = 0;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	type = fp->f_type;
 	fdrop(fp, td);
@@ -2581,10 +2593,12 @@ linux_ioctl_socket(struct thread *td, st
 static int
 linux_ioctl_private(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error, type;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0)
 		return (error);
 	type = fp->f_type;
 	fdrop(fp, td);
@@ -2606,11 +2620,13 @@ linux_ioctl_drm(struct thread *td, struc
 static int
 linux_ioctl_sg(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	u_long cmd;
 	int error;
 
-	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) {
+	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+	if (error != 0) {
 		printf("sg_linux_ioctl: fget returned %d\n", error);
 		return (error);
 	}
@@ -2828,6 +2844,7 @@ linux_v4l_cliplist_copy(struct l_video_w
 static int
 linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 	struct video_tuner vtun;
@@ -2845,7 +2862,9 @@ linux_ioctl_v4l(struct thread *td, struc
 	case LINUX_VIDIOCSCHAN:		args->cmd = VIDIOCSCHAN; break;
 
 	case LINUX_VIDIOCGTUNER:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun));
 		if (error) {
@@ -2863,7 +2882,9 @@ linux_ioctl_v4l(struct thread *td, struc
 		return (error);
 
 	case LINUX_VIDIOCSTUNER:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun));
 		if (error) {
@@ -2880,7 +2901,9 @@ linux_ioctl_v4l(struct thread *td, struc
 	case LINUX_VIDIOCCAPTURE:	args->cmd = VIDIOCCAPTURE; break;
 
 	case LINUX_VIDIOCGWIN:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = fo_ioctl(fp, VIDIOCGWIN, &vwin, td->td_ucred, td);
 		if (!error) {
@@ -2892,7 +2915,9 @@ linux_ioctl_v4l(struct thread *td, struc
 		return (error);
 
 	case LINUX_VIDIOCSWIN:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = copyin((void *) args->arg, &l_vwin, sizeof(l_vwin));
 		if (error) {
@@ -2915,7 +2940,9 @@ linux_ioctl_v4l(struct thread *td, struc
 		return (error);
 
 	case LINUX_VIDIOCGFBUF:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = fo_ioctl(fp, VIDIOCGFBUF, &vbuf, td->td_ucred, td);
 		if (!error) {
@@ -2927,7 +2954,9 @@ linux_ioctl_v4l(struct thread *td, struc
 		return (error);
 
 	case LINUX_VIDIOCSFBUF:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = copyin((void *) args->arg, &l_vbuf, sizeof(l_vbuf));
 		if (error) {
@@ -2955,7 +2984,9 @@ linux_ioctl_v4l(struct thread *td, struc
 	case LINUX_VIDIOCGPLAYINFO:	args->cmd = VIDIOCGPLAYINFO; break;
 
 	case LINUX_VIDIOCSMICROCODE:
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error != 0)
 			return (error);
 		error = copyin((void *) args->arg, &l_vcode, sizeof(l_vcode));
 		if (error) {
@@ -3108,6 +3139,7 @@ bsd_to_linux_v4l2_format(struct v4l2_for
 static int
 linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args)
 {
+	cap_rights_t rights;
 	struct file *fp;
 	int error;
 	struct v4l2_format vformat;
@@ -3199,7 +3231,9 @@ linux_ioctl_v4l2(struct thread *td, stru
 		error = copyin((void *)args->arg, &l_vformat, sizeof(l_vformat));
 		if (error)
 			return (error);
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error)
 			return (error);
 		if (linux_to_bsd_v4l2_format(&l_vformat, &vformat) != 0)
 			error = EINVAL;
@@ -3222,7 +3256,9 @@ linux_ioctl_v4l2(struct thread *td, stru
 		if (error)
 			return (error);
 		linux_to_bsd_v4l2_standard(&l_vstd, &vstd);
-		if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
+		error = fget(td, args->fd,
+		    cap_rights_init(&rights, CAP_IOCTL), &fp);
+		if (error)
 			return (error);
 		error = fo_ioctl(fp, VIDIOC_ENUMSTD, (caddr_t)&vstd,
 		    td->td_ucred, td);
@@ -3244,7 +3280,9 @@ linux_ioctl_v4l2(struct thread *td, stru
 				sizeof(struct l_v4l2_input));
 		if (error != 0)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list