Page MenuHomeFreeBSD

D49717.id153533.diff
No OneTemporary

D49717.id153533.diff

diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1150,6 +1150,56 @@
uap->mode));
}
+/*
+ * Validate open(2) flags and convert access mode flags (O_RDONLY etc.) to their
+ * in-kernel representations (FREAD etc.).
+ */
+static int
+openflags(int *flagsp)
+{
+ int flags;
+
+ /*
+ * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags
+ * may be specified. On the other hand, for O_PATH any mode
+ * except O_EXEC is ignored.
+ */
+ flags = *flagsp;
+ if ((flags & O_PATH) != 0) {
+ flags &= ~O_ACCMODE;
+ } else if ((flags & O_EXEC) != 0) {
+ if ((flags & O_ACCMODE) != 0)
+ return (EINVAL);
+ } else if ((flags & O_ACCMODE) == O_ACCMODE) {
+ return (EINVAL);
+ } else {
+ flags = FFLAGS(flags);
+ }
+ *flagsp = flags;
+ return (0);
+}
+
+static void
+finit_open(struct file *fp, struct vnode *vp, int flags)
+{
+ fp->f_vnode = vp;
+
+ /*
+ * If the file wasn't claimed by devfs or fifofs, bind it to the normal
+ * vnode operations here.
+ */
+ if (fp->f_ops == &badfileops) {
+ KASSERT(vp->v_type != VFIFO || (flags & O_PATH) != 0,
+ ("Unexpected fifo fp %p vp %p", fp, vp));
+ if ((flags & O_PATH) != 0) {
+ finit(fp, (flags & FMASK) | (fp->f_flag & FKQALLOWED),
+ DTYPE_VNODE, NULL, &path_fileops);
+ } else {
+ finit_vnode(fp, flags, NULL, &vnops);
+ }
+ }
+}
+
/*
* If fpp != NULL, opened file is not installed into the file
* descriptor table, instead it is returned in *fpp. This is
@@ -1179,21 +1229,9 @@
cap_rights_init_one(&rights, CAP_LOOKUP);
flags_to_rights(flags, &rights);
- /*
- * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags
- * may be specified. On the other hand, for O_PATH any mode
- * except O_EXEC is ignored.
- */
- if ((flags & O_PATH) != 0) {
- flags &= ~O_ACCMODE;
- } else if ((flags & O_EXEC) != 0) {
- if (flags & O_ACCMODE)
- return (EINVAL);
- } else if ((flags & O_ACCMODE) == O_ACCMODE) {
- return (EINVAL);
- } else {
- flags = FFLAGS(flags);
- }
+ error = openflags(&flags);
+ if (error != 0)
+ return (error);
/*
* Allocate a file structure. The descriptor to reference it
@@ -1244,28 +1282,7 @@
NDFREE_PNBUF(&nd);
vp = nd.ni_vp;
- /*
- * Store the vnode, for any f_type. Typically, the vnode use
- * count is decremented by direct call to vn_closefile() for
- * files that switched type in the cdevsw fdopen() method.
- */
- fp->f_vnode = vp;
-
- /*
- * If the file wasn't claimed by devfs bind it to the normal
- * vnode operations here.
- */
- if (fp->f_ops == &badfileops) {
- KASSERT(vp->v_type != VFIFO || (flags & O_PATH) != 0,
- ("Unexpected fifo fp %p vp %p", fp, vp));
- if ((flags & O_PATH) != 0) {
- finit(fp, (flags & FMASK) | (fp->f_flag & FKQALLOWED),
- DTYPE_VNODE, NULL, &path_fileops);
- } else {
- finit_vnode(fp, flags, NULL, &vnops);
- }
- }
-
+ finit_open(fp, vp, flags);
VOP_UNLOCK(vp);
if (flags & O_TRUNC) {
error = fo_truncate(fp, 0, td->td_ucred, td);
@@ -4653,21 +4670,20 @@
struct vnode *vp;
struct fhandle fhp;
struct file *fp;
- int fmode, error;
- int indx;
+ int error, indx;
bool named_attr;
error = priv_check(td, PRIV_VFS_FHOPEN);
if (error != 0)
return (error);
+
indx = -1;
- fmode = FFLAGS(flags);
- /* why not allow a non-read/write open for our lockd? */
- if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
- return (EINVAL);
+ error = openflags(&flags);
+ if (error != 0)
+ return (error);
error = copyin(u_fhp, &fhp, sizeof(fhp));
if (error != 0)
- return(error);
+ return (error);
/* find the mount point */
mp = vfs_busyfs(&fhp.fh_fsid);
if (mp == NULL)
@@ -4685,8 +4701,8 @@
*/
named_attr = (vn_irflag_read(vp) &
(VIRF_NAMEDDIR | VIRF_NAMEDATTR)) != 0;
- if ((named_attr && (fmode & O_NAMEDATTR) == 0) ||
- (!named_attr && (fmode & O_NAMEDATTR) != 0)) {
+ if ((named_attr && (flags & O_NAMEDATTR) == 0) ||
+ (!named_attr && (flags & O_NAMEDATTR) != 0)) {
vput(vp);
return (ENOATTR);
}
@@ -4704,7 +4720,7 @@
#ifdef INVARIANTS
td->td_dupfd = -1;
#endif
- error = vn_open_vnode(vp, fmode, td->td_ucred, td, fp);
+ error = vn_open_vnode(vp, flags, td->td_ucred, td, fp);
if (error != 0) {
KASSERT(fp->f_ops == &badfileops,
("VOP_OPEN in fhopen() set f_ops"));
@@ -4717,16 +4733,15 @@
#ifdef INVARIANTS
td->td_dupfd = 0;
#endif
- fp->f_vnode = vp;
- finit_vnode(fp, fmode, NULL, &vnops);
+ finit_open(fp, vp, flags);
VOP_UNLOCK(vp);
- if ((fmode & O_TRUNC) != 0) {
+ if ((flags & O_TRUNC) != 0) {
error = fo_truncate(fp, 0, td->td_ucred, td);
if (error != 0)
goto bad;
}
- error = finstall(td, fp, &indx, fmode, NULL);
+ error = finstall(td, fp, &indx, flags, NULL);
bad:
fdrop(fp, td);
td->td_retval[0] = indx;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -432,6 +432,9 @@
accmode_t accmode;
int error;
+ KASSERT((fmode & O_PATH) == 0 || (fmode & O_ACCMODE) == 0,
+ ("%s: O_PATH and O_ACCMODE are mutually exclusive", __func__));
+
if (vp->v_type == VLNK) {
if ((fmode & O_PATH) == 0 || (fmode & FEXEC) != 0)
return (EMLINK);

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 12:52 PM (2 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30758249
Default Alt Text
D49717.id153533.diff (5 KB)

Event Timeline