svn commit: r206821 - stable/8/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Sun Apr 18 22:51:16 UTC 2010
Author: rmacklem
Date: Sun Apr 18 22:51:15 2010
New Revision: 206821
URL: http://svn.freebsd.org/changeset/base/206821
Log:
MFC: r206170
Harden the experimental NFS server a little, by adding extra checks
in the readdir functions for non-positive byte count arguments.
For the negative case, set it to the maximum allowable, since it
was actually a large positive value (unsigned) on the wire.
Also, fix up the readdir function comment a bit.
Modified:
stable/8/sys/fs/nfsserver/nfs_nfsdport.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/dev/uath/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdport.c Sun Apr 18 22:34:29 2010 (r206820)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdport.c Sun Apr 18 22:51:15 2010 (r206821)
@@ -1397,24 +1397,16 @@ nfsvno_fillattr(struct nfsrv_descript *n
* nfs readdir service
* - mallocs what it thinks is enough to read
* count rounded up to a multiple of DIRBLKSIZ <= NFS_MAXREADDIR
- * - calls nfsvno_readdir()
+ * - calls VOP_READDIR()
* - loops around building the reply
* if the output generated exceeds count break out of loop
* The NFSM_CLGET macro is used here so that the reply will be packed
* tightly in mbuf clusters.
- * - it only knows that it has encountered eof when the nfsvno_readdir()
- * reads nothing
- * - as such one readdir rpc will return eof false although you are there
- * and then the next will return eof
* - it trims out records with d_fileno == 0
* this doesn't matter for Unix clients, but they might confuse clients
* for other os'.
* - it trims out records with d_type == DT_WHT
* these cannot be seen through NFS (unless we extend the protocol)
- * NB: It is tempting to set eof to true if the nfsvno_readdir() reads less
- * than requested, but this may not apply to all filesystems. For
- * example, client NFS does not { although it is never remote mounted
- * anyhow }
* The alternate call nfsrvd_readdirplus() does lookups as well.
* PS: The NFS protocol spec. does not clarify what the "count" byte
* argument is a count of.. just name strings and file id's or the
@@ -1456,7 +1448,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd
}
toff = off;
cnt = fxdr_unsigned(int, *tl);
- if (cnt > NFS_SRVMAXDATA(nd))
+ if (cnt > NFS_SRVMAXDATA(nd) || cnt < 0)
cnt = NFS_SRVMAXDATA(nd);
siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
fullsiz = siz;
@@ -1474,6 +1466,13 @@ nfsrvd_readdir(struct nfsrv_descript *nd
nd->nd_repstat = NFSERR_BAD_COOKIE;
#endif
}
+ if (nd->nd_repstat == 0 && cnt == 0) {
+ if (nd->nd_flag & ND_NFSV2)
+ /* NFSv2 does not have NFSERR_TOOSMALL */
+ nd->nd_repstat = EPERM;
+ else
+ nd->nd_repstat = NFSERR_TOOSMALL;
+ }
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE,
@@ -1696,7 +1695,7 @@ nfsrvd_readdirplus(struct nfsrv_descript
* Use the server's maximum data transfer size as the upper bound
* on reply datalen.
*/
- if (cnt > NFS_SRVMAXDATA(nd))
+ if (cnt > NFS_SRVMAXDATA(nd) || cnt < 0)
cnt = NFS_SRVMAXDATA(nd);
/*
@@ -1705,7 +1704,7 @@ nfsrvd_readdirplus(struct nfsrv_descript
* so I set it to cnt for that case. I also round it up to the
* next multiple of DIRBLKSIZ.
*/
- if (siz == 0)
+ if (siz <= 0)
siz = cnt;
siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
More information about the svn-src-stable
mailing list