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