aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2025-04-20 23:19:05 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2025-04-20 23:19:05 +0000
commitee95e4d02dbdd59daed46bbf2170897c1c2a8894 (patch)
tree90a16516dc690e5b8dd080d74ae8961a68757fb1
parent92439940517ba57954f6b7f50545a43e506540f1 (diff)
vfs_vnops.c: Fix the named attribute check for open
In vn_open_cred(), the correct check for O_NAMEDATTR was done when O_CREAT was specified, but the file already exists. (Added by commit 2ec2ba7e232d, which will be listed as a Fixes: in the commit log message.) This correct check was not copied to the case where O_CREAT has not been specified. This patch fixes this. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D49898 Fixes: 2ec2ba7e232d ("vfs: Add VFS/syscall support for Solaris style extended attributes")
-rw-r--r--sys/kern/vfs_vnops.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 4a369559111e..6ad9c75564c3 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -223,6 +223,25 @@ open2nameif(int fmode, u_int vn_open_flags)
}
/*
+ * For the O_NAMEDATTR case, check for a valid use of it.
+ */
+static int
+vfs_check_namedattr(struct vnode *vp)
+{
+ int error;
+ short irflag;
+
+ error = 0;
+ irflag = vn_irflag_read(vp);
+ if ((vp->v_mount->mnt_flag & MNT_NAMEDATTR) == 0 ||
+ ((irflag & VIRF_NAMEDATTR) != 0 && vp->v_type != VREG))
+ error = EINVAL;
+ else if ((irflag & (VIRF_NAMEDDIR | VIRF_NAMEDATTR)) == 0)
+ error = ENOATTR;
+ return (error);
+}
+
+/*
* Common code for vnode open operations via a name lookup.
* Lookup the vnode and invoke VOP_CREATE if needed.
* Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
@@ -334,17 +353,7 @@ restart:
goto bad;
}
if ((fmode & O_NAMEDATTR) != 0) {
- short irflag;
-
- irflag = vn_irflag_read(vp);
- if ((vp->v_mount->mnt_flag &
- MNT_NAMEDATTR) == 0 ||
- ((irflag & VIRF_NAMEDATTR) != 0 &&
- vp->v_type != VREG))
- error = EINVAL;
- else if ((irflag & (VIRF_NAMEDDIR |
- VIRF_NAMEDATTR)) == 0)
- error = ENOATTR;
+ error = vfs_check_namedattr(vp);
if (error != 0)
goto bad;
} else if (vp->v_type == VDIR) {
@@ -363,10 +372,10 @@ restart:
if ((error = namei(ndp)) != 0)
return (error);
vp = ndp->ni_vp;
- if ((fmode & O_NAMEDATTR) != 0 && (vp->v_mount->mnt_flag &
- MNT_NAMEDATTR) == 0) {
- error = EINVAL;
- goto bad;
+ if ((fmode & O_NAMEDATTR) != 0) {
+ error = vfs_check_namedattr(vp);
+ if (error != 0)
+ goto bad;
}
}
error = vn_open_vnode(vp, fmode, cred, curthread, fp);