PERFORCE change 134006 for review

Robert Watson rwatson at FreeBSD.org
Thu Jan 24 05:16:16 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=134006

Change 134006 by rwatson at rwatson_freebsd_capabilities on 2008/01/24 13:15:28

	Update consumers of fget() and friends to specify capability
	rights masks.  Not all cases are satisfactory, and portalfs is
	just plain scary.
	
	In getsock(), don't need to test DTYPE_CAPABILITY anymore, just
	use cap_fextract().

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/sys/amd64/linux32/linux32_machdep.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_file.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_ioctl.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_socket.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_stats.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_fcntl.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_filio.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_ioctl.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_stream.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/aac/aac_linux.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/amr/amr_linux.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/hwpmc/hwpmc_logging.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/iscsi/initiator/iscsi.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/mfi/mfi_linux.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/snp/snp.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/dev/tdfx/tdfx_linux.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/fs/fdescfs/fdesc_vnops.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/fs/portalfs/portal_vfsops.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/fs/portalfs/portal_vnops.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/gnu/fs/xfs/xfs_dfrag.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/i386/ibcs2/ibcs2_fcntl.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/i386/ibcs2/ibcs2_ioctl.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/i386/linux/linux_machdep.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_event.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_generic.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_pipe.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/uipc_mqueue.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/uipc_syscalls.c#4 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/vfs_aio.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/vfs_syscalls.c#4 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/netgraph/ng_socket.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/nfsserver/nfs_syscalls.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/security/mac/mac_syscalls.c#2 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/vm/vm_mmap.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/sys/amd64/linux32/linux32_machdep.c#2 (text+ko) ====

@@ -844,7 +844,7 @@
 		 * protection options specified.
 		 */
 
-		if ((error = fget(td, bsd_args.fd, &fp)) != 0)
+		if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0)
 			return (error);
 		if (fp->f_type != DTYPE_VNODE) {
 			fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_file.c#2 (text+ko) ====

@@ -138,7 +138,7 @@
 	     * having the same filedesc could use that fd without
 	     * checking below.
 	     */
-	    error = fget(td, fd, &fp);
+	    error = fget(td, fd, CAP_IOCTL, &fp);
 	    if (!error) {
 		    sx_slock(&proctree_lock);
 		    PROC_LOCK(p);
@@ -212,7 +212,11 @@
 		vref(dvp);
 	   	FILEDESC_SUNLOCK(fdp);
 	} else {
-	   	error = fget(td, dirfd, &fp);
+		/*
+		 * XXXRW: Not ideal, possibly fixed with native freebsd _at
+		 * support?
+		 */
+	   	error = fget(td, dirfd, CAP_FCHDIR, &fp);
 		if (error)
 		   	return (error);
 		dvp = fp->f_vnode;
@@ -898,8 +902,9 @@
 	error = pread(td, &bsd);
 
 	if (error == 0) {
+		/* XXXRW: No capability rights should be OK. */
    	   	/* This seems to violate POSIX but linux does it */
-   	   	if ((error = fgetvp(td, uap->fd, &vp)) != 0)
+   	   	if ((error = fgetvp(td, uap->fd, 0, &vp)) != 0)
    		   	return (error);
 		if (vp->v_type == VDIR) {
    		   	vrele(vp);
@@ -1236,8 +1241,12 @@
 		 * XXX some Linux applications depend on F_SETOWN having no
 		 * significant effect for pipes (SIGIO is not delivered for
 		 * pipes under Linux-2.2.35 at least).
+		 *
+		 * Don't really need to check CAP_FCNTL here since real work
+		 * will depend on kern_fnctl(), but it's will give the right
+		 * error in the EINVAL case.
 		 */
-		error = fget(td, args->fd, &fp);
+		error = fget(td, args->fd, CAP_FCNTL, &fp);
 		if (error)
 			return (error);
 		if (fp->f_type == DTYPE_PIPE) {

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_ioctl.c#2 (text+ko) ====

@@ -162,7 +162,7 @@
 	u_int sectorsize, fwcylinders, fwheads, fwsectors;
 	off_t mediasize, bytespercyl;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 	case LINUX_HDIO_GET_GEO:
@@ -243,7 +243,7 @@
 	u_int sectorsize;
 	off_t mediasize;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 	case LINUX_BLKGETSIZE:
@@ -664,7 +664,7 @@
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 
 	switch (args->cmd & 0xffff) {
@@ -1397,7 +1397,7 @@
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 
@@ -1913,7 +1913,7 @@
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	switch (args->cmd & 0xffff) {
 
@@ -2297,7 +2297,7 @@
 	ifp = NULL;
 	error = 0;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	type = fp->f_type;
 	fdrop(fp, td);
@@ -2523,7 +2523,7 @@
 	struct file *fp;
 	int error, type;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	type = fp->f_type;
 	fdrop(fp, td);
@@ -2549,7 +2549,7 @@
 	u_long cmd;
 	int error;
 
-	if ((error = fget(td, args->fd, &fp)) != 0) {
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) {
 		printf("sg_linux_ioctl: fget returned %d\n", error);
 		return (error);
 	}
@@ -2605,7 +2605,7 @@
 		    (unsigned long)args->cmd);
 #endif
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
 		fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_socket.c#2 (text+ko) ====

@@ -669,8 +669,10 @@
 	 * XXXRW: Instead of using fgetsock(), check that it is a
 	 * socket and use the file descriptor reference instead of
 	 * creating a new one.
+	 *
+	 * XXXRW: No capability rights required here?
 	 */
-	error = fgetsock(td, linux_args.s, &so, &fflag);
+	error = fgetsock(td, linux_args.s, 0, &so, &fflag);
 	if (error == 0) {
 		error = EISCONN;
 		if (fflag & FNONBLOCK) {

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/linux/linux_stats.c#2 (text+ko) ====

@@ -102,8 +102,11 @@
 	struct file *fp;
 	int major, minor;
 
+	/*
+	 * XXXRW: No capability rights required here.
+	 */
 	if ((!S_ISCHR(buf->st_mode) && !S_ISBLK(buf->st_mode)) ||
-	    fget(td, fd, &fp) != 0)
+	    fget(td, fd, 0, &fp) != 0)
 		return;
 	if (fp->f_vnode != NULL &&
 	    fp->f_vnode->v_un.vu_cdev != NULL &&

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_fcntl.c#2 (text+ko) ====

@@ -261,7 +261,7 @@
 	int error, *retval;
 
 	retval = td->td_retval;
-	if ((error = fgetvp(td, fd, &vp)) != 0)
+	if ((error = fgetvp(td, fd, CAP_REVOKE, &vp)) != 0)
 		return (error);
 
 	if (vp->v_type != VCHR && vp->v_type != VBLK) {
@@ -313,7 +313,7 @@
 	/*
 	 * We only support truncating the file.
 	 */
-	if ((error = fget(td, fd, &fp)) != 0)
+	if ((error = fget(td, fd, CAP_FTRUNCATE, &fp)) != 0)
 		return (error);
 
 	vp = fp->f_vnode;
@@ -392,7 +392,7 @@
 #if defined(NOTYET)
 		struct file	*fp;
 
-		error = fget(td, retval, &fp);
+		error = fget(td, retval, CAP_IOCTL, &fp);
 		PROC_UNLOCK(p);
 		/*
 		 * we may have lost a race the above open() and

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_filio.c#2 (text+ko) ====

@@ -120,7 +120,7 @@
      ra.buf = uap->buf;
      ra.nbyte = uap->nbyte;
 
-     if (fget(td, uap->fd, &fp) != 0) {
+     if (fget(td, uap->fd, CAP_READ, &fp) != 0) {
        DPRINTF(("Something fishy with the user-supplied file descriptor...\n"));
        return EBADF;
      }

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_ioctl.c#2 (text+ko) ====

@@ -103,7 +103,7 @@
 	retval = td->td_retval;
 	cmd = uap->com;
 
-	if ((error = fget(td, uap->fd, &fp)) != 0)
+	if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 
 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {

==== //depot/projects/trustedbsd/capabilities/src/sys/compat/svr4/svr4_stream.c#2 (text+ko) ====

@@ -1448,7 +1448,7 @@
 	struct file     *fp;
 	int error;
 
-	if ((error = fget(td, uap->fd, &fp)) != 0) {
+	if ((error = fget(td, uap->fd, CAP_WRITE, &fp)) != 0) {
 #ifdef DEBUG_SVR4
 	        uprintf("putmsg: bad fp\n");
 #endif
@@ -1620,7 +1620,7 @@
 	struct file     *fp;
 	int error;
 
-	if ((error = fget(td, uap->fd, &fp)) != 0) {
+	if ((error = fget(td, uap->fd, CAP_READ, &fp)) != 0) {
 #ifdef DEBUG_SVR4
 	        uprintf("getmsg: bad fp\n");
 #endif

==== //depot/projects/trustedbsd/capabilities/src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c#2 (text+ko) ====

@@ -1468,7 +1468,8 @@
 	    strchr(zc->zc_value, '@') == NULL)
 		return (EINVAL);
 
-	error = fget_read(td, zc->zc_cookie, &fp);
+	/* XXXRW: Is this right? */
+	error = fget_read(td, zc->zc_cookie, CAP_IOCTL, &fp);
 	if (error)
 		return (error);
 
@@ -1515,7 +1516,8 @@
 	}
 
 	fd = zc->zc_cookie;
-	error = fget_write(td, fd, &fp);
+	/* XXXRW: Is this right? */
+	error = fget_write(td, fd, CAP_IOCTL, &fp);
 	if (error) {
 		dmu_objset_close(tosnap);
 		if (fromsnap)

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/aac/aac_linux.c#2 (text+ko) ====

@@ -78,7 +78,7 @@
 	u_long cmd;
 	int error;
 
-	if ((error = fget(td, args->fd, &fp)) != 0)
+	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	cmd = args->cmd;
 

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/amr/amr_linux.c#2 (text+ko) ====

@@ -74,7 +74,7 @@
 	struct file *fp;
 	int error;
 
-	if ((error = fget(p, args->fd, &fp)) != 0)
+	if ((error = fget(p, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p);
 	fdrop(fp, p);

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/hwpmc/hwpmc_logging.c#2 (text+ko) ====

@@ -564,7 +564,7 @@
 		po->po_file));
 
 	/* get a reference to the file state */
-	error = fget_write(curthread, logfd, &po->po_file);
+	error = fget_write(curthread, logfd, CAP_WRITE, &po->po_file);
 	if (error)
 		goto error;
 

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/iscsi/initiator/iscsi.c#2 (text+ko) ====

@@ -390,11 +390,15 @@
      if(sp->soc != NULL)
 	  isc_stop_receiver(sp);
 
-     error = fget(td, fd, &sp->fp);
+     /*
+      * XXXRW: Possibly should be CAP_SOCK_ALL?
+      */
+     error = fget(td, fd, CAP_READ | CAP_WRITE | CAP_SHUTDOWN, &sp->fp);
      if(error)
 	  return error;
 
-     if((error = fgetsock(td, fd, &sp->soc, 0)) == 0) {
+     if((error = fgetsock(td, fd, CAP_READ | CAP_WRITE | CAP_SHUTDOWN,
+	&sp->soc, 0)) == 0) {
 	  sp->td = td;
 	  isc_start_receiver(sp);
      }

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/mfi/mfi_linux.c#2 (text) ====

@@ -95,7 +95,7 @@
 		break;
 	}
 
-	if ((error = fget(p, args->fd, &fp)) != 0)
+	if ((error = fget(p, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	error = fo_ioctl(fp, cmd, (caddr_t)args->arg, p->td_ucred, p);
 	fdrop(fp, p);

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/snp/snp.c#2 (text+ko) ====

@@ -504,7 +504,12 @@
 		if (s < 0)
 			return (snp_down(snp));
 
-		if (fget(td, s, &fp) != 0)
+		/*
+		 * XXXRW: It's not immediately clear what capability rights
+		 * to check for here, so check for read and write as those
+		 * are the implications of snooping.
+		 */
+		if (fget(td, s, CAP_READ | CAP_WRITE, &fp) != 0)
 			return (EINVAL);
 		if (fp->f_type != DTYPE_VNODE ||
 		    fp->f_vnode->v_type != VCHR ||

==== //depot/projects/trustedbsd/capabilities/src/sys/dev/tdfx/tdfx_linux.c#2 (text) ====

@@ -53,7 +53,7 @@
 
    struct file *fp;
 
-   if ((error = fget(td, args->fd, &fp)) != 0)
+   if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 	   return (error);
    /* We simply copy the data and send it right to ioctl */
    copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio));

==== //depot/projects/trustedbsd/capabilities/src/sys/fs/fdescfs/fdesc_vnops.c#2 (text+ko) ====

@@ -225,7 +225,10 @@
 		fd = 10 * fd + *pname++ - '0';
 	}
 
-	if ((error = fget(td, fd, &fp)) != 0)
+	/*
+	 * XXXRW: 'fp' isn't actually used so no rights to check?
+	 */
+	if ((error = fget(td, fd, 0, &fp)) != 0)
 		goto bad;
 
 	error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp, td);
@@ -310,7 +313,7 @@
 	case Fdesc:
 		fd = VTOFDESC(vp)->fd_fd;
 
-		if ((error = fget(ap->a_td, fd, &fp)) != 0)
+		if ((error = fget(ap->a_td, fd, CAP_FSTAT, &fp)) != 0)
 			return (error);
 
 		bzero(&stb, sizeof(stb));

==== //depot/projects/trustedbsd/capabilities/src/sys/fs/portalfs/portal_vfsops.c#2 (text+ko) ====

@@ -110,7 +110,10 @@
 	if (error)
 		return (error);
 
-	if ((error = fget(td, v, &fp)) != 0)
+	/*
+	 * XXXRW: I suppose we want CAP_SOCK_ALL here?
+	 */
+	if ((error = fget(td, v, CAP_READ | CAP_WRITE, &fp)) != 0)
 		return (error);
         if (fp->f_type != DTYPE_SOCKET) {
 		fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/fs/portalfs/portal_vnops.c#2 (text+ko) ====

@@ -407,8 +407,12 @@
 	/*
 	 * Check that the mode the file is being opened for is a subset
 	 * of the mode of the existing descriptor.
+	 *
+	 * XXXRW: It is stunningly non-obvious how to handle this with
+	 * respect to capabilities.  Does that mean this is simply a bad
+	 * idea?
 	 */
-	if ((error = fget(td, fd, &fp)) != 0)
+	if ((error = fget(td, fd, 0, &fp)) != 0)
 		goto bad;
 	if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
 		fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/gnu/fs/xfs/xfs_dfrag.c#2 (text+ko) ====

@@ -79,7 +79,8 @@
 	}
 
 	/* Pull information for the target fd */
-	if (fgetvp(td, (int)sxp->sx_fdtarget, &bvp) != 0) {
+	if (fgetvp(td, (int)sxp->sx_fdtarget, CAP_READ | CAP_WRITE, &bvp)
+	    != 0) {
 		error = XFS_ERROR(EINVAL);
 		goto error0;
 	}
@@ -91,7 +92,8 @@
 		goto error0;
 	}
 
-	if (fgetvp(td, (int)sxp->sx_fdtmp, &btvp) != 0) {
+	if (fgetvp(td, (int)sxp->sx_fdtmp, CAP_READ | CAP_WRITE, &btvp) !=
+	    0) {
 		error = XFS_ERROR(EINVAL);
 		goto error0;
 	}

==== //depot/projects/trustedbsd/capabilities/src/sys/i386/ibcs2/ibcs2_fcntl.c#2 (text+ko) ====

@@ -202,7 +202,10 @@
 		struct file *fp;
 		int error;
 
-		error = fget(td, td->td_retval[0], &fp);
+		/*
+		 * XXXRW: Think more about the capability right to use here.
+		 */
+		error = fget(td, td->td_retval[0], CAP_IOCTL, &fp);
 		PROC_UNLOCK(p);
 		if (error)
 			return (EBADF);

==== //depot/projects/trustedbsd/capabilities/src/sys/i386/ibcs2/ibcs2_ioctl.c#2 (text+ko) ====

@@ -347,7 +347,11 @@
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, uap->fd, &fp)) != 0) {
+	/*
+	 * XXXRW: Possibily we should switch (cmd) to generate a rights mask
+	 * to use here, see IBCS2_SIOCSOCKSYS for example.
+	 */
+	if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) {
 		DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
 			 uap->fd));
 		return EBADF;

==== //depot/projects/trustedbsd/capabilities/src/sys/i386/linux/linux_machdep.c#2 (text+ko) ====

@@ -693,9 +693,12 @@
 		 * The file descriptor fildes is opened with
 		 * read permission, regardless of the
 		 * protection options specified.
+		 *
+		 * XXXRW: The real work is done in the FreeBSD mmap(), so
+		 * just checking CAP_MMAP here is fine.
 		 */
 
-		if ((error = fget(td, bsd_args.fd, &fp)) != 0)
+		if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0)
 			return (error);
 		if (fp->f_type != DTYPE_VNODE) {
 			fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_event.c#2 (text+ko) ====

@@ -649,7 +649,7 @@
 	struct file *fp;
 	int i, n, nerrors, error;
 
-	if ((error = fget(td, fd, &fp)) != 0)
+	if ((error = fget(td, fd, CAP_EVENT, &fp)) != 0)
 		return (error);
 	if ((error = kqueue_acquire(fp, &kq)) != 0)
 		goto done_norel;
@@ -804,7 +804,7 @@
 findkn:
 	if (fops->f_isfd) {
 		KASSERT(td != NULL, ("td is NULL"));
-		error = fget(td, kev->ident, &fp);
+		error = fget(td, kev->ident, CAP_EVENT, &fp);
 		if (error)
 			goto done;
 
@@ -1948,7 +1948,7 @@
 	struct file *fp;
 	int error;
 
-	if ((error = fget(td, fd, &fp)) != 0)
+	if ((error = fget(td, fd, CAP_EVENT, &fp)) != 0)
 		return (error);
 	if ((error = kqueue_acquire(fp, &kq)) != 0)
 		goto noacquire;

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_generic.c#2 (text+ko) ====

@@ -229,7 +229,7 @@
 	struct file *fp;
 	int error;
 
-	error = fget_read(td, fd, &fp);
+	error = fget_read(td, fd, CAP_READ | CAP_SEEK, &fp);
 	if (error)
 		return (error);
 	error = dofileread(td, fd, fp, auio, (off_t)-1, 0);
@@ -272,7 +272,7 @@
 	struct file *fp;
 	int error;
 
-	error = fget_read(td, fd, &fp);
+	error = fget_read(td, fd, CAP_READ, &fp);
 	if (error)
 		return (error);
 	if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE))
@@ -438,7 +438,7 @@
 	struct file *fp;
 	int error;
 
-	error = fget_write(td, fd, &fp);
+	error = fget_write(td, fd, CAP_WRITE | CAP_SEEK, &fp);
 	if (error)
 		return (error);
 	error = dofilewrite(td, fd, fp, auio, (off_t)-1, 0);
@@ -481,7 +481,7 @@
 	struct file *fp;
 	int error;
 
-	error = fget_write(td, fd, &fp);
+	error = fget_write(td, fd, CAP_WRITE, &fp);
 	if (error)
 		return (error);
 	if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE))
@@ -563,7 +563,7 @@
 	AUDIT_ARG(fd, fd);
 	if (length < 0)
 		return (EINVAL);
-	error = fget(td, fd, &fp);
+	error = fget(td, fd, CAP_FTRUNCATE, &fp);
 	if (error)
 		return (error);
 	AUDIT_ARG(file, td->td_proc, fp);
@@ -692,7 +692,7 @@
 	int error;
 	int tmp;
 
-	if ((error = fget(td, fd, &fp)) != 0)
+	if ((error = fget(td, fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
 		fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_pipe.c#2 (text+ko) ====


==== //depot/projects/trustedbsd/capabilities/src/sys/kern/uipc_mqueue.c#2 (text+ko) ====

@@ -2038,19 +2038,19 @@
 	return (error);
 }
 
-typedef int (*_fgetf)(struct thread *, int, struct file **);
+typedef int (*_fgetf)(struct thread *, int, cap_rights_t, struct file **);
 
 /*
  * Get message queue by giving file slot
  */
 static int
-_getmq(struct thread *td, int fd, _fgetf func,
+_getmq(struct thread *td, int fd, cap_rights_t rights, _fgetf func,
        struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq)
 {
 	struct mqfs_node *pn;
 	int error;
 
-	error = func(td, fd, fpp);
+	error = func(td, fd, rights, fpp);
 	if (error)
 		return (error);
 	if (&mqueueops != (*fpp)->f_ops) {
@@ -2069,21 +2069,21 @@
 getmq(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn,
 	struct mqueue **pmq)
 {
-	return _getmq(td, fd, fget, fpp, ppn, pmq);
+	return _getmq(td, fd, CAP_EVENT, fget, fpp, ppn, pmq);
 }
 
 static __inline int
 getmq_read(struct thread *td, int fd, struct file **fpp,
 	 struct mqfs_node **ppn, struct mqueue **pmq)
 {
-	return _getmq(td, fd, fget_read, fpp, ppn, pmq);
+	return _getmq(td, fd, CAP_READ, fget_read, fpp, ppn, pmq);
 }
 
 static __inline int
 getmq_write(struct thread *td, int fd, struct file **fpp,
 	struct mqfs_node **ppn, struct mqueue **pmq)
 {
-	return _getmq(td, fd, fget_write, fpp, ppn, pmq);
+	return _getmq(td, fd, CAP_WRITE, fget_write, fpp, ppn, pmq);
 }
 
 int
@@ -2165,7 +2165,7 @@
 	struct filedesc *fdp;
 	struct proc *p;
 	struct mqueue *mq;
-	struct file *fp;
+	struct file *fp, *fp2;
 	struct mqueue_notifier *nt, *newnt = NULL;
 	int error;
 
@@ -2189,8 +2189,12 @@
 		return (error);
 again:
 	FILEDESC_SLOCK(fdp);
-	if (fget_locked(fdp, uap->mqd) != fp) {
+	error = cap_fextract(fget_locked(fdp, uap->mqd), CAP_EVENT, &fp2);
+	if (error) {
 		FILEDESC_SUNLOCK(fdp);
+		goto out;
+	}
+	if (fp2 != fp) {
 		error = EBADF;
 		goto out;
 	}

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/uipc_syscalls.c#4 (text+ko) ====

@@ -176,12 +176,10 @@
 	 * the file descriptor referenced by the capability.
 	 */
 #ifdef CAPABILITIES
-	if (fp->f_type == DTYPE_CAPABILITY) {
-		error = cap_fget(fp, rights, &fp);
-		if (error) {
-			fp = NULL;
-			goto out;
-		}
+	error = cap_fextract(fp, rights, &fp);
+	if (error) {
+		fp = NULL;
+		goto out;
 	}
 #endif /* CAPABILITIES */
 	if (fp->f_type != DTYPE_SOCKET) {
@@ -1839,7 +1837,8 @@
 	 * File offset must be positive.  If it goes beyond EOF
 	 * we send only the header/trailer and no payload data.
 	 */
-	if ((error = fgetvp_read(td, uap->fd, &vp)) != 0)
+	if ((error = fgetvp_read(td, uap->fd, CAP_READ | CAP_SEEK, &vp))
+	    != 0)
 		goto out;
 	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
@@ -2279,7 +2278,7 @@
 	u_int fflag;
 
 	fdp = td->td_proc->p_fd;
-	error = fgetsock(td, uap->sd, &head, &fflag);
+	error = fgetsock(td, uap->sd, CAP_PEELOFF, &head, &fflag);
 	if (error)
 		goto done2;
 	error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name);

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/vfs_aio.c#2 (text+ko) ====

@@ -1400,17 +1400,30 @@
 		aiocbe->uaiocb.aio_lio_opcode = type;
 	opcode = aiocbe->uaiocb.aio_lio_opcode;
 
-	/* Fetch the file object for the specified file descriptor. */
+	/*
+	 * Validate the opcode and fetch the file object for the specified
+	 * file descriptor.
+	 *
+	 * XXXRW: Moved the opcode validation up here so that we don't
+	 * retrieve a file descriptor without knowing what the capability
+	 * should be.
+	 */
 	fd = aiocbe->uaiocb.aio_fildes;
 	switch (opcode) {
 	case LIO_WRITE:
-		error = fget_write(td, fd, &fp);
+		error = fget_write(td, fd, CAP_WRITE | CAP_AIO, &fp);
 		break;
 	case LIO_READ:
-		error = fget_read(td, fd, &fp);
+		error = fget_read(td, fd, CAP_READ | CAP_AIO, &fp);
+		break;
+	case LIO_SYNC:
+		error = fget(td, fd, CAP_FSYNC | CAP_AIO, &fp);
+		break;
+	case LIO_NOP:
+		error = fget(td, fd, CAP_AIO, &fp);
 		break;
 	default:
-		error = fget(td, fd, &fp);
+		error = EINVAL;
 	}
 	if (error) {
 		uma_zfree(aiocb_zone, aiocbe);
@@ -1446,11 +1459,6 @@
 		uma_zfree(aiocb_zone, aiocbe);
 		return (0);
 	}
-	if ((opcode != LIO_READ) && (opcode != LIO_WRITE) &&
-	    (opcode != LIO_SYNC)) {
-		error = EINVAL;
-		goto aqueue_fail;
-	}
 
 	if (aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_KEVENT)
 		goto no_kqueue;
@@ -1790,7 +1798,7 @@
 	struct vnode *vp;
 
 	/* Lookup file object. */
-	error = fget(td, uap->fd, &fp);
+	error = fget(td, uap->fd, CAP_AIO, &fp);
 	if (error)
 		return (error);
 

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/vfs_syscalls.c#4 (text+ko) ====

@@ -166,12 +166,10 @@
 	 * the file descriptor referenced by the capability.
 	 */
 #ifdef CAPABILITIES
-	if (fp->f_type == DTYPE_CAPABILITY) {
-		error = cap_fget(fp, rights, &fp);
-		if (error) {
-			fp = NULL;
-			goto out;
-		}
+	error = cap_fextract(fp, rights, &fp);
+	if (error) {
+		fp = NULL;
+		goto out;
 	}
 #endif /* CAPABILITIES */
 	if (fp->f_vnode == NULL) {
@@ -1833,7 +1831,7 @@
 	int error, noneg;
 	int vfslocked;
 
-	if ((error = fget(td, uap->fd, &fp)) != 0)
+	if ((error = fget(td, uap->fd, CAP_SEEK, &fp)) != 0)
 		return (error);
 	if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) {
 		fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/netgraph/ng_socket.c#2 (text+ko) ====

@@ -676,9 +676,12 @@
 	}
 
 	/* Check that the FD given is legit. and change it to a pointer to a
-	 * struct file. */
+	 * struct file.
+	 *
+	 * XXXRW: For now, no capability right required to pass an fd.
+	 */
 	fd = CMSG_DATA(cm);
-	if ((error = fget(td, fd, &fp)) != 0)
+	if ((error = fget(td, fd, 0, &fp)) != 0)
 		return (error);
 
 	/* Depending on what kind of resource it is, act differently. For

==== //depot/projects/trustedbsd/capabilities/src/sys/nfsserver/nfs_syscalls.c#2 (text+ko) ====

@@ -147,7 +147,12 @@
 		error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
 		if (error)
 			return (error);
-		if ((error = fget(td, nfsdarg.sock, &fp)) != 0)
+		/*
+		 * XXXRW: Really want CAP_SOCK_ALL?
+		 */
+		if ((error = fget(td, nfsdarg.sock, CAP_READ | CAP_WRITE |
+		    CAP_GETSOCKNAME | CAP_BIND | CAP_CONNECT | CAP_EVENT,
+		    &fp)) != 0)
 			return (error);
 		if (fp->f_type != DTYPE_SOCKET) {
 			fdrop(fp, td);

==== //depot/projects/trustedbsd/capabilities/src/sys/security/mac/mac_syscalls.c#2 (text+ko) ====

@@ -244,7 +244,7 @@
 	}
 
 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-	error = fget(td, uap->fd, &fp);
+	error = fget(td, uap->fd, CAP_MAC_GET, &fp);
 	if (error)
 		goto out;
 
@@ -427,7 +427,7 @@
 		return (error);
 	}
 
-	error = fget(td, uap->fd, &fp);
+	error = fget(td, uap->fd, CAP_MAC_SET, &fp);
 	if (error)
 		goto out;
 

==== //depot/projects/trustedbsd/capabilities/src/sys/vm/vm_mmap.c#2 (text+ko) ====

@@ -304,8 +304,11 @@
 		/*
 		 * Mapping file, get fp for validation and
 		 * don't let the descriptor disappear on us if we block.
+		 *
+		 * XXXRW: should extract capability rights and incorporate
+		 * them into maxprot, just file flags.
 		 */
-		if ((error = fget(td, uap->fd, &fp)) != 0)
+		if ((error = fget(td, uap->fd, CAP_MMAP, &fp)) != 0)
 			goto done;
 		if (fp->f_type == DTYPE_SHM) {
 			handle = fp->f_data;


More information about the p4-projects mailing list