git: ee95e4d02dbd - main - vfs_vnops.c: Fix the named attribute check for open
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 20 Apr 2025 23:20:09 UTC
The branch main has been updated by rmacklem:
URL: https://cgit.FreeBSD.org/src/commit/?id=ee95e4d02dbdd59daed46bbf2170897c1c2a8894
commit ee95e4d02dbdd59daed46bbf2170897c1c2a8894
Author: Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2025-04-20 23:19:05 +0000
Commit: Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2025-04-20 23:19:05 +0000
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")
---
sys/kern/vfs_vnops.c | 39 ++++++++++++++++++++++++---------------
1 file 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
@@ -222,6 +222,25 @@ open2nameif(int fmode, u_int vn_open_flags)
return (res);
}
+/*
+ * 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.
@@ -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);