Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150576624
D49717.id153533.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D49717.id153533.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D49717: fhopen: Enable handling of O_PATH, fix some bugs
Attached
Detach File
Event Timeline
Log In to Comment