diff options
Diffstat (limited to 'sys/fs/nfsclient')
| -rw-r--r-- | sys/fs/nfsclient/nfs_clrpcops.c | 39 | ||||
| -rw-r--r-- | sys/fs/nfsclient/nfs_clvfsops.c | 8 | ||||
| -rw-r--r-- | sys/fs/nfsclient/nfs_clvnops.c | 8 | 
3 files changed, 38 insertions, 17 deletions
| diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index ad9404a18fc8..b61218958550 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -2212,7 +2212,7 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iomode,  				NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED  					+ NFSX_VERF);  				rlen = fxdr_unsigned(int, *tl++); -				if (rlen == 0) { +				if (rlen <= 0 || rlen > len) {  					error = NFSERR_IO;  					goto nfsmout;  				} else if (rlen < len) { @@ -4162,9 +4162,12 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,  		    NFSATTRBIT_TIMECREATE))  			NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE);  		if (!NFSISSET_ATTRBIT(&dnp->n_vattr.na_suppattr, +		    NFSATTRBIT_ARCHIVE) || +		    !NFSISSET_ATTRBIT(&dnp->n_vattr.na_suppattr,  		    NFSATTRBIT_HIDDEN) ||  		    !NFSISSET_ATTRBIT(&dnp->n_vattr.na_suppattr,  		    NFSATTRBIT_SYSTEM)) { +			NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE);  			NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN);  			NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM);  		} @@ -5281,7 +5284,7 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred,  	struct nfsrv_descript nfsd;  	struct nfsrv_descript *nd = &nfsd;  	u_char *cp, *cp2, *fhp; -	int error, cnt, len, setnil; +	int error, cnt, i, len, setnil;  	u_int32_t *opcntp;  	nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL, 0, @@ -5322,8 +5325,12 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred,  	if (error)  		return (error);  	if (nd->nd_repstat == 0) { -		NFSM_DISSECT(tl, u_int32_t *, (3 + 2 * cnt) * NFSX_UNSIGNED); -		tl += (2 + 2 * cnt); +		NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED); +		tl += 2; +		for (i = 0; i < cnt; i++) { +			NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); +			tl++; +		}  		if ((len = fxdr_unsigned(int, *tl)) <= 0 ||  			len > NFSX_FHMAX) {  			nd->nd_repstat = NFSERR_BADXDR; @@ -5596,7 +5603,7 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep,  	}  	*tl++ = txdr_unsigned(4096);		/* Max response size cached */  	*tl++ = txdr_unsigned(20);		/* Max operations */ -	*tl++ = txdr_unsigned(64);		/* Max slots */ +	*tl++ = txdr_unsigned(NFSV4_SLOTS);	/* Max slots */  	*tl = 0;				/* No rdma ird */  	/* Fill in back channel attributes. */ @@ -5665,6 +5672,11 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep,  		sep->nfsess_maxcache = fxdr_unsigned(int, *tl++);  		tl++;  		sep->nfsess_foreslots = fxdr_unsigned(uint16_t, *tl++); +		if (sep->nfsess_foreslots == 0) { +			error = NFSERR_BADXDR; +			goto nfsmout; +		} else if (sep->nfsess_foreslots > NFSV4_SLOTS) +			sep->nfsess_foreslots = NFSV4_SLOTS;  		NFSCL_DEBUG(4, "fore slots=%d\n", (int)sep->nfsess_foreslots);  		irdcnt = fxdr_unsigned(int, *tl);  		if (irdcnt < 0 || irdcnt > 1) { @@ -5678,6 +5690,8 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep,  		NFSM_DISSECT(tl, uint32_t *, 7 * NFSX_UNSIGNED);  		tl += 5;  		sep->nfsess_backslots = fxdr_unsigned(uint16_t, *tl); +		if (sep->nfsess_backslots > NFSV4_CBSLOTS) +			sep->nfsess_backslots = NFSV4_CBSLOTS;  		NFSCL_DEBUG(4, "back slots=%d\n", (int)sep->nfsess_backslots);  	}  	error = nd->nd_repstat; @@ -5797,7 +5811,8 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *deviceid, int layouttype,  			NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);  			stripecnt = fxdr_unsigned(int, *tl);  			NFSCL_DEBUG(4, "stripecnt=%d\n", stripecnt); -			if (stripecnt < 1 || stripecnt > 4096) { +			if (stripecnt >= MHLEN / NFSX_UNSIGNED || +			    stripecnt < 1) {  				printf("pNFS File layout devinfo stripecnt %d:"  				    " out of range\n", stripecnt);  				error = NFSERR_BADXDR; @@ -7246,7 +7261,7 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,  		NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED + NFSX_VERF);  		rlen = fxdr_unsigned(int, *tl++);  		NFSCL_DEBUG(4, "nfsrpc_writeds: len=%d rlen=%d\n", len, rlen); -		if (rlen == 0) { +		if (rlen <= 0 || rlen > len) {  			error = NFSERR_IO;  			goto nfsmout;  		} else if (rlen < len) { @@ -8243,7 +8258,7 @@ nfsrv_parseug(struct nfsrv_descript *nd, int dogrp, uid_t *uidp, gid_t *gidp,      NFSPROC_T *p)  {  	uint32_t *tl; -	char *cp, *str, str0[NFSV4_SMALLSTR + 1]; +	char *str, str0[NFSV4_SMALLSTR + 1];  	uint32_t len = 0;  	int error = 0; @@ -8266,9 +8281,9 @@ nfsrv_parseug(struct nfsrv_descript *nd, int dogrp, uid_t *uidp, gid_t *gidp,  		str = malloc(len + 1, M_TEMP, M_WAITOK);  	else  		str = str0; -	NFSM_DISSECT(cp, char *, NFSM_RNDUP(len)); -	NFSBCOPY(cp, str, len); -	str[len] = '\0'; +	error = nfsrv_mtostr(nd, str, len); +	if (error != 0) +		goto nfsmout;  	NFSCL_DEBUG(4, "nfsrv_parseug: str=%s\n", str);  	if (dogrp != 0)  		error = nfsv4_strtogid(nd, str, len, gidp); @@ -9745,7 +9760,7 @@ nfsm_split(struct mbuf *mp, uint64_t xfer)  		pgno++;  	} while (pgno < m->m_epg_npgs);  	if (pgno == m->m_epg_npgs) -		panic("nfsm_split: eroneous ext_pgs mbuf"); +		panic("nfsm_split: erroneous ext_pgs mbuf");  	m2 = mb_alloc_ext_pgs(M_WAITOK, mb_free_mext_pgs, 0);  	m2->m_epg_flags |= EPG_FLAG_ANON; diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 5ea7eab07632..212c88f28930 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -927,7 +927,7 @@ nfs_mount(struct mount *mp)  	struct vnode *vp;  	struct thread *td;  	char *hst; -	u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; +	u_char nfh[NFSX_FHMAX], krbname[100], *dirpath, srvkrbname[100];  	char *cp, *opt, *name, *secname, *tlscertname;  	int nametimeo = NFS_DEFAULT_NAMETIMEO;  	int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; @@ -943,6 +943,7 @@ nfs_mount(struct mount *mp)  	newflag = 0;  	tlscertname = NULL;  	hst = malloc(MNAMELEN, M_TEMP, M_WAITOK); +	dirpath = malloc(MNAMELEN, M_TEMP, M_WAITOK);  	if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {  		error = EINVAL;  		goto out; @@ -1329,7 +1330,7 @@ nfs_mount(struct mount *mp)  			goto out;  	} else if (nfs_mount_parse_from(mp->mnt_optnew,  	    &args.hostname, (struct sockaddr_in **)&nam, dirpath, -	    sizeof(dirpath), &dirlen) == 0) { +	    MNAMELEN, &dirlen) == 0) {  		has_nfs_from_opt = 1;  		bcopy(args.hostname, hst, MNAMELEN);  		hst[MNAMELEN - 1] = '\0'; @@ -1387,7 +1388,7 @@ nfs_mount(struct mount *mp)  	if (has_nfs_from_opt == 0) {  		if (vfs_getopt(mp->mnt_optnew,  		    "dirpath", (void **)&name, NULL) == 0) -			strlcpy(dirpath, name, sizeof (dirpath)); +			strlcpy(dirpath, name, MNAMELEN);  		else  			dirpath[0] = '\0';  		dirlen = strlen(dirpath); @@ -1472,6 +1473,7 @@ out:  		MNT_IUNLOCK(mp);  	}  	free(hst, M_TEMP); +	free(dirpath, M_TEMP);  	return (error);  } diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index e9ae91e046e7..f80cf30669ca 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1081,12 +1081,14 @@ nfs_setattr(struct vop_setattr_args *ap)  #endif  	/* -	 * Only setting of UF_HIDDEN and UF_SYSTEM are supported and +	 * Only setting of UF_ARCHIVE, UF_HIDDEN and UF_SYSTEM are supported and  	 * only for NFSv4 servers that support them.  	 */  	nmp = VFSTONFS(vp->v_mount);  	if (vap->va_flags != VNOVAL && (!NFSHASNFSV4(nmp) || -	    (vap->va_flags & ~(UF_HIDDEN | UF_SYSTEM)) != 0 || +	    (vap->va_flags & ~(UF_ARCHIVE | UF_HIDDEN | UF_SYSTEM)) != 0 || +	    ((vap->va_flags & UF_ARCHIVE) != 0 && +	     !NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, NFSATTRBIT_ARCHIVE)) ||  	    ((vap->va_flags & UF_HIDDEN) != 0 &&  	     !NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, NFSATTRBIT_HIDDEN)) ||  	    ((vap->va_flags & UF_SYSTEM) != 0 && @@ -4835,6 +4837,8 @@ nfs_pathconf(struct vop_pathconf_args *ap)  		break;  	case _PC_HAS_HIDDENSYSTEM:  		if (NFS_ISV4(vp) && NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, +		    NFSATTRBIT_ARCHIVE) && +		    NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,  		    NFSATTRBIT_HIDDEN) &&  		    NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,  		    NFSATTRBIT_SYSTEM)) | 
