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:
+11
-8
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user