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