NFS: readdir shouldn't read beyond the reply returned by the server
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 16 Nov 2010 01:26:22 +0000 (20:26 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 16 Nov 2010 01:44:29 +0000 (20:44 -0500)
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/dir.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c

index c6ce8af266ed891df0e41502285dec34b9e87db3..c9196c9cf5a64d1520b85a92b0f4f3ba1f843cfc 100644 (file)
@@ -573,11 +573,13 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        if (!pages_ptr)
                goto out_release_array;
        do {
+               unsigned int pglen;
                status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
 
                if (status < 0)
                        break;
-               status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE);
+               pglen = status;
+               status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen);
                if (status < 0) {
                        if (status == -ENOSPC)
                                status = 0;
index e6bf45710cc7fcd0348459ed7a27cc9454ee7e88..2563f765c9b4ba49b37615657f4c3f5f76e7576d 100644 (file)
@@ -423,7 +423,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
        struct page **page;
        size_t hdrlen;
        unsigned int pglen, recvd;
-       int status, nr = 0;
+       int status;
 
        if ((status = ntohl(*p++)))
                return nfs_stat_to_errno(status);
@@ -443,7 +443,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
        if (pglen > recvd)
                pglen = recvd;
        page = rcvbuf->pages;
-       return nr;
+       return pglen;
 }
 
 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
index d9a5e832c2579f9b20c0164944ae139509d8fb79..748dc91a4a147466529d9b1b49a20cc0ab2aad93 100644 (file)
@@ -555,7 +555,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
        struct page **page;
        size_t hdrlen;
        u32 recvd, pglen;
-       int status, nr = 0;
+       int status;
 
        status = ntohl(*p++);
        /* Decode post_op_attrs */
@@ -586,7 +586,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
                pglen = recvd;
        page = rcvbuf->pages;
 
-       return nr;
+       return pglen;
 }
 
 __be32 *
index 0f24cdf2cb132b1ad7018a520a7abbea753ce330..6a653ffd8e4e121e37c29d88ff2f5b0b4dbe264f 100644 (file)
@@ -2852,8 +2852,10 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
        res.pgbase = args.pgbase;
        status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
-       if (status == 0)
+       if (status >= 0) {
                memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
+               status += args.pgbase;
+       }
 
        nfs_invalidate_atime(dir);
 
index f313c4cce7e4d1d087b8a1b47b55f769edf40a21..b7a204ff6fe1504efe287b7620532407cc692f89 100644 (file)
@@ -4518,7 +4518,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        xdr_read_pages(xdr, pglen);
 
 
-       return 0;
+       return pglen;
 }
 
 static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)