From: NeilBrown <neilb@cse.unsw.edu.au>

From: "J. Bruce Fields" <bfields@fieldses.org>

Fix out-of-spec errors in nfs4 readdir.  Add checks for bad cookie values.
DESC
nfsd4_readdir build fix
EDESC

crufty old gcc:

fs/nfsd/nfs4proc.c: In function `nfsd4_readdir':
fs/nfsd/nfs4proc.c:533: array index in non-array initializer
fs/nfsd/nfs4proc.c:533: (near initialization for `zeroverf')
fs/nfsd/nfs4proc.c:533: warning: missing braces around initializer
fs/nfsd/nfs4proc.c:533: warning: (near initialization for `zeroverf.data')



---

 25-akpm/fs/nfsd/nfs4proc.c |    6 +++++-
 25-akpm/fs/nfsd/nfs4xdr.c  |    2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff -puN fs/nfsd/nfs4proc.c~kNFSdv4-4-of-10-nfsd4_readdir-fixes fs/nfsd/nfs4proc.c
--- 25/fs/nfsd/nfs4proc.c~kNFSdv4-4-of-10-nfsd4_readdir-fixes	2004-04-12 22:50:59.461856888 -0700
+++ 25-akpm/fs/nfsd/nfs4proc.c	2004-04-12 22:51:05.504938200 -0700
@@ -448,6 +448,9 @@ out:
 static inline int
 nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir)
 {
+	u64 cookie = readdir->rd_cookie;
+	static const nfs4_verifier zeroverf;
+
 	/* no need to check permission - this will be done in nfsd_readdir() */
 
 	if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
@@ -456,7 +459,8 @@ nfsd4_readdir(struct svc_rqst *rqstp, st
 	readdir->rd_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0;
 	readdir->rd_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1;
 
-	if (readdir->rd_cookie > ~(u32)0)
+	if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) ||
+	    (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
 		return nfserr_bad_cookie;
 
 	readdir->rd_rqstp = rqstp;
diff -puN fs/nfsd/nfs4xdr.c~kNFSdv4-4-of-10-nfsd4_readdir-fixes fs/nfsd/nfs4xdr.c
--- 25/fs/nfsd/nfs4xdr.c~kNFSdv4-4-of-10-nfsd4_readdir-fixes	2004-04-12 22:50:59.463856584 -0700
+++ 25-akpm/fs/nfsd/nfs4xdr.c	2004-04-12 22:50:59.469855672 -0700
@@ -2179,6 +2179,8 @@ nfsd4_encode_readdir(struct nfsd4_compou
 	    readdir->common.err == nfserr_toosmall &&
 	    readdir->buffer == page) 
 		nfserr = nfserr_toosmall;
+	if (nfserr == nfserr_symlink)
+		nfserr = nfserr_notdir;
 	if (nfserr)
 		goto err_no_verf;
 

_