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);