git: 5648c1d6f3b0 - main - ufs_aclcheck(): accurately dereference vp->v_mount
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 21 Mar 2025 23:40:40 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=5648c1d6f3b0d8f4d67d2e6ec56dd2abcbd8fff5 commit 5648c1d6f3b0d8f4d67d2e6ec56dd2abcbd8fff5 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2025-03-20 18:10:56 +0000 Commit: Konstantin Belousov <kib@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 */