diff options
author | iedowse <iedowse@FreeBSD.org> | 2002-01-13 05:36:05 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2002-01-13 05:36:05 +0000 |
commit | a2d0f7e01a2246e45ce6707cf802a6548673446c (patch) | |
tree | 8bb0b2e081b2068336c469f210f6ebe76c340b8b /sys/nfsserver | |
parent | d3725c9bff8c5f1ba4af4eb0e3e07d0de20d08e6 (diff) | |
download | FreeBSD-src-a2d0f7e01a2246e45ce6707cf802a6548673446c.zip FreeBSD-src-a2d0f7e01a2246e45ce6707cf802a6548673446c.tar.gz |
It is required by VOP_CREATE, VOP_MKNOD, VOP_SYMLINK and VOP_MKDIR
that va_mode of the supplied attributes is filled in with a valid
file mode (i.e not VNOVAL, and only ALLPERM bits set). However,
some NFS server op functions didn't guarantee this for all possible
request messages:
If a V3 client chose not include to a mode specification, we could
end up creating an ffs inode with mode 0177777, requiring a manual
fsck on the next reboot. Fix this by setting va_mode to 0 before
calling the VOP if a mode hasn't been supplied by the client.
In nfsrv_symlink(), S_IFMT bits supplied by a V2 client could end
up in the va_mode passed to VOP_SYMLINK with similar effects. We
now use the macro nfstov_mode() to correctly mask the bits.
Diffstat (limited to 'sys/nfsserver')
-rw-r--r-- | sys/nfsserver/nfs_serv.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 46c00d5..0db5c9d 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -1679,8 +1679,6 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, cp = nfsm_dissect(caddr_t, NFSX_V3CREATEVERF); bcopy(cp, cverf, NFSX_V3CREATEVERF); exclusive_flag = 1; - if (nd.ni_vp == NULL) - vap->va_mode = 0; break; }; vap->va_type = VREG; @@ -1715,6 +1713,8 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * nd.ni_vp will also be non-NULL in that case. */ if (nd.ni_vp == NULL) { + if (vap->va_mode == (mode_t)VNOVAL) + vap->va_mode = 0; if (vap->va_type == VREG || vap->va_type == VSOCK) { error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); if (error) @@ -1938,6 +1938,8 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, goto out; } vap->va_type = vtyp; + if (vap->va_mode == (mode_t)VNOVAL) + vap->va_mode = 0; if (vtyp == VSOCK) { vrele(nd.ni_startdir); nd.ni_startdir = NULL; @@ -2560,7 +2562,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsm_mtouio(&io, len2); if (!v3) { sp = nfsm_dissect(struct nfsv2_sattr *, NFSX_V2SATTR); - vap->va_mode = fxdr_unsigned(u_int16_t, sp->sa_mode); + vap->va_mode = nfstov_mode(sp->sa_mode); } *(pathcp + len2) = '\0'; if (nd.ni_vp) { @@ -2572,6 +2574,8 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * issue symlink op. SAVESTART is set so the underlying path component * is only freed by the VOP if an error occurs. */ + if (vap->va_mode == (mode_t)VNOVAL) + vap->va_mode = 0; error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp); if (error) NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2755,6 +2759,8 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * component is freed by the VOP call. This will fill-in * nd.ni_vp, reference, and exclusively lock it. */ + if (vap->va_mode == (mode_t)VNOVAL) + vap->va_mode = 0; error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); NDFREE(&nd, NDF_ONLY_PNBUF); vpexcl = 1; |