The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=5648c1d6f3b0d8f4d67d2e6ec56dd2abcbd8fff5

commit 5648c1d6f3b0d8f4d67d2e6ec56dd2abcbd8fff5
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-03-20 18:10:56 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-03-21 23:40:00 +0000

    ufs_aclcheck(): accurately dereference vp->v_mount
    
    The argument vnode passed to VOP_ACLCHECK() is not locked, it is not
    safe to deref a_vp->v_mount without ensuring that the pointer is
    non-null and stable.
    
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/ufs/ufs/ufs_acl.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c
index 49bd686a0d96..4b6cabc2ab30 100644
--- a/sys/ufs/ufs/ufs_acl.c
+++ b/sys/ufs/ufs/ufs_acl.c
@@ -609,11 +609,11 @@ ufs_setacl(struct vop_setacl_args *ap)
 }
 
 static int
-ufs_aclcheck_nfs4(struct vop_aclcheck_args *ap)
+ufs_aclcheck_nfs4(struct vop_aclcheck_args *ap, struct mount *mp)
 {
        int is_directory = 0;
 
-       if ((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 0)
+       if ((mp->mnt_flag & MNT_NFS4ACLS) == 0)
                return (EINVAL);
 
        /*
@@ -631,10 +631,9 @@ ufs_aclcheck_nfs4(struct vop_aclcheck_args *ap)
 }
 
 static int
-ufs_aclcheck_posix1e(struct vop_aclcheck_args *ap)
+ufs_aclcheck_posix1e(struct vop_aclcheck_args *ap, struct mount *mp)
 {
-
-       if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0)
+       if ((mp->mnt_flag & MNT_ACLS) == 0)
                return (EINVAL);
 
        /*
@@ -667,14 +666,18 @@ ufs_aclcheck_posix1e(struct vop_aclcheck_args *ap)
 int
 ufs_aclcheck(struct vop_aclcheck_args *ap)
 {
+       struct mount *mp;
 
-       if ((ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) == 0)
+       mp = atomic_load_ptr(&ap->a_vp->v_mount);
+       if (mp == NULL)
+               return (EBADF);
+       if ((mp->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) == 0)
                return (EOPNOTSUPP);
 
        if (ap->a_type == ACL_TYPE_NFS4)
-               return (ufs_aclcheck_nfs4(ap));
+               return (ufs_aclcheck_nfs4(ap, mp));
 
-       return (ufs_aclcheck_posix1e(ap));
+       return (ufs_aclcheck_posix1e(ap, mp));
 }
 
 #endif /* !UFS_ACL */

Reply via email to