Date: Thu, 24 Jan 2008 13:16:15 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 134006 for review Message-ID: <200801241316.m0ODGFeV055524@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=134006 Change 134006 by rwatson@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801241316.m0ODGFeV055524>