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
This commit is contained in:
Konstantin Belousov 2025-03-20 20:10:56 +02:00
parent d7352b2d57
commit 5648c1d6f3

View file

@ -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 */