mirror of
https://git.freebsd.org/src.git
synced 2026-01-11 19:57:22 +00:00
nfsd: Fix handling of hidden/system during Open/Create
Some checks are pending
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (push) Waiting to run
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (push) Waiting to run
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (push) Waiting to run
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (push) Waiting to run
Cross-build Kernel / amd64 macos-latest (clang-18) (push) Waiting to run
Cross-build Kernel / aarch64 macos-latest (clang-18) (push) Waiting to run
Some checks are pending
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (push) Waiting to run
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (push) Waiting to run
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (push) Waiting to run
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (push) Waiting to run
Cross-build Kernel / amd64 macos-latest (clang-18) (push) Waiting to run
Cross-build Kernel / aarch64 macos-latest (clang-18) (push) Waiting to run
When an NFSv4.n client specifies settings for the archive, hidden and/or system attributes during a Open/Create, the Open/Create fails for ZFS. This is caused by ZFS doing a secpolicy_xvattr() call, which fails for non-root. If this check is bypassed, ZFS panics. This patch resolves the problem by disabling va_flags for the VOP_CREATE() call in the NFSv4.n server and then setting the flags with a subsequent VOP_SETATTR(). This problem only affects FreeBSD-15 and main, since the archive, system and hidden attributes are not enabled for FreeBSD-14. I think a similar problem exists for the NFSv4.n Open/Create/Exclusive_41, but that will be resolved in a future commit. Note that the Linux, Solaris and FreeBSD clients do not set archive, hidden or system for Open/Create, so the bug does not affect mounts from those clients. PR: 292283 Reported by: Aurelien Couderc <aurelien.couderc2002@gmail.com> Tested by: Aurelien Couderc <aurelien.couderc2002@gmail.com> MFC after: 2 weeks
This commit is contained in:
parent
0aaa95ae02
commit
a6d57f312f
2 changed files with 49 additions and 0 deletions
|
|
@ -1977,6 +1977,7 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
|||
struct nfsexstuff nes;
|
||||
struct thread *p = curthread;
|
||||
uint32_t oldrepstat;
|
||||
u_long savflags;
|
||||
|
||||
if (ndp->ni_vp == NULL) {
|
||||
/*
|
||||
|
|
@ -1991,6 +1992,15 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
|||
}
|
||||
if (!nd->nd_repstat) {
|
||||
if (ndp->ni_vp == NULL) {
|
||||
/*
|
||||
* Most file systems ignore va_flags for
|
||||
* VOP_CREATE(), however setting va_flags
|
||||
* for VOP_CREATE() causes problems for ZFS.
|
||||
* So disable them and let nfsrv_fixattr()
|
||||
* do them, as required.
|
||||
*/
|
||||
savflags = nvap->na_flags;
|
||||
nvap->na_flags = VNOVAL;
|
||||
nd->nd_repstat = VOP_CREATE(ndp->ni_dvp,
|
||||
&ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr);
|
||||
/* For a pNFS server, create the data file on a DS. */
|
||||
|
|
@ -2003,6 +2013,7 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
|||
nfsrv_pnfscreate(ndp->ni_vp, &nvap->na_vattr,
|
||||
cred, p);
|
||||
}
|
||||
nvap->na_flags = savflags;
|
||||
VOP_VPUT_PAIR(ndp->ni_dvp, nd->nd_repstat == 0 ?
|
||||
&ndp->ni_vp : NULL, false);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
|
|
|
|||
|
|
@ -1697,6 +1697,44 @@ nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp,
|
|||
NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_OWNERGROUP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For archive, ZFS sets it by default for new files,
|
||||
* so if specified, it must be set or cleared.
|
||||
* For hidden and system, no file system sets them
|
||||
* by default upon creation, so they only need to be
|
||||
* set and not cleared.
|
||||
*/
|
||||
if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ARCHIVE)) {
|
||||
if (nva.na_flags == VNOVAL)
|
||||
nva.na_flags = 0;
|
||||
if ((nvap->na_flags & UF_ARCHIVE) != 0)
|
||||
nva.na_flags |= UF_ARCHIVE;
|
||||
change++;
|
||||
NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_ARCHIVE);
|
||||
}
|
||||
if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_HIDDEN)) {
|
||||
if ((nvap->na_flags & UF_HIDDEN) != 0) {
|
||||
if (nva.na_flags == VNOVAL)
|
||||
nva.na_flags = 0;
|
||||
nva.na_flags |= UF_HIDDEN;
|
||||
change++;
|
||||
NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_HIDDEN);
|
||||
} else {
|
||||
NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_HIDDEN);
|
||||
}
|
||||
}
|
||||
if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SYSTEM)) {
|
||||
if ((nvap->na_flags & UF_SYSTEM) != 0) {
|
||||
if (nva.na_flags == VNOVAL)
|
||||
nva.na_flags = 0;
|
||||
nva.na_flags |= UF_SYSTEM;
|
||||
change++;
|
||||
NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_SYSTEM);
|
||||
} else {
|
||||
NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_SYSTEM);
|
||||
}
|
||||
}
|
||||
if (change) {
|
||||
error = nfsvno_setattr(vp, &nva, nd->nd_cred, p, exp);
|
||||
if (error) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue