git: e05e33041c25 - main - vfs: Don't clobber namei flags in vn_open_cred()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 May 2025 15:42:33 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=e05e33041c252dc236939683c01ca4b7b083562c
commit e05e33041c252dc236939683c01ca4b7b083562c
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-05-28 13:35:24 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-05-28 15:41:53 +0000
vfs: Don't clobber namei flags in vn_open_cred()
Otherwise NAMEILOOKUP is cleared. More generally it seems quite
surprising that the flags set by vn_open_cred() callers are not
automatically preserved. Modify open2nameif() such that it takes
already-set namei flags into account.
Reviewed by: olce, kib
Fixes: 7587f6d4840f ("namei: Make stackable filesystems check harder for jail roots")
Differential Revision: https://reviews.freebsd.org/D50531
---
sys/kern/vfs_vnops.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 696f5c11c8fc..9b891019bbc6 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -187,11 +187,11 @@ vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp)
}
static uint64_t
-open2nameif(int fmode, u_int vn_open_flags)
+open2nameif(int fmode, u_int vn_open_flags, uint64_t cn_flags)
{
uint64_t res;
- res = ISOPEN | LOCKLEAF;
+ res = ISOPEN | LOCKLEAF | cn_flags;
if ((fmode & O_RESOLVE_BENEATH) != 0)
res |= RBENEATH;
if ((fmode & O_EMPTY_PATH) != 0)
@@ -202,12 +202,17 @@ open2nameif(int fmode, u_int vn_open_flags)
res |= OPENWRITE;
if ((fmode & O_NAMEDATTR) != 0)
res |= OPENNAMED | CREATENAMED;
+ if ((fmode & O_NOFOLLOW) != 0)
+ res &= ~FOLLOW;
if ((vn_open_flags & VN_OPEN_NOAUDIT) == 0)
res |= AUDITVNODE1;
+ else
+ res &= ~AUDITVNODE1;
if ((vn_open_flags & VN_OPEN_NOCAPCHECK) != 0)
res |= NOCAPCHECK;
if ((vn_open_flags & VN_OPEN_WANTIOCTLCAPS) != 0)
res |= WANTIOCTLCAPS;
+
return (res);
}
@@ -258,7 +263,9 @@ restart:
return (EINVAL);
else if ((fmode & (O_CREAT | O_DIRECTORY)) == O_CREAT) {
ndp->ni_cnd.cn_nameiop = CREATE;
- ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags);
+ ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags,
+ ndp->ni_cnd.cn_flags);
+
/*
* Set NOCACHE to avoid flushing the cache when
* rolling in many files at once.
@@ -267,8 +274,8 @@ restart:
* exist despite NOCACHE.
*/
ndp->ni_cnd.cn_flags |= LOCKPARENT | NOCACHE | NC_KEEPPOSENTRY;
- if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
- ndp->ni_cnd.cn_flags |= FOLLOW;
+ if ((fmode & O_EXCL) != 0)
+ ndp->ni_cnd.cn_flags &= ~FOLLOW;
if ((vn_open_flags & VN_OPEN_INVFS) == 0)
bwillwrite();
if ((error = namei(ndp)) != 0)
@@ -348,9 +355,8 @@ restart:
}
} else {
ndp->ni_cnd.cn_nameiop = LOOKUP;
- ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags);
- ndp->ni_cnd.cn_flags |= (fmode & O_NOFOLLOW) != 0 ? NOFOLLOW :
- FOLLOW;
+ ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags,
+ ndp->ni_cnd.cn_flags);
if ((fmode & FWRITE) == 0)
ndp->ni_cnd.cn_flags |= LOCKSHARED;
if ((error = namei(ndp)) != 0)