diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-11-15 20:26:22 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-11-15 20:44:29 -0500 |
commit | ac39612824e1fad8baf82c2841e42b2142af3445 (patch) | |
tree | 12a841ca751a50f324dc97963579002943d0c3c9 /fs | |
parent | 8cd51a0ccd1beda4482507769887c0be9d70f8c1 (diff) |
NFS: readdir shouldn't read beyond the reply returned by the server
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/dir.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 2 |
5 files changed, 11 insertions, 7 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c6ce8af266ed..c9196c9cf5a6 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -573,11 +573,13 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
573 | if (!pages_ptr) | 573 | if (!pages_ptr) |
574 | goto out_release_array; | 574 | goto out_release_array; |
575 | do { | 575 | do { |
576 | unsigned int pglen; | ||
576 | status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); | 577 | status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); |
577 | 578 | ||
578 | if (status < 0) | 579 | if (status < 0) |
579 | break; | 580 | break; |
580 | status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE); | 581 | pglen = status; |
582 | status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen); | ||
581 | if (status < 0) { | 583 | if (status < 0) { |
582 | if (status == -ENOSPC) | 584 | if (status == -ENOSPC) |
583 | status = 0; | 585 | status = 0; |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index e6bf45710cc7..2563f765c9b4 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -423,7 +423,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) | |||
423 | struct page **page; | 423 | struct page **page; |
424 | size_t hdrlen; | 424 | size_t hdrlen; |
425 | unsigned int pglen, recvd; | 425 | unsigned int pglen, recvd; |
426 | int status, nr = 0; | 426 | int status; |
427 | 427 | ||
428 | if ((status = ntohl(*p++))) | 428 | if ((status = ntohl(*p++))) |
429 | return nfs_stat_to_errno(status); | 429 | return nfs_stat_to_errno(status); |
@@ -443,7 +443,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) | |||
443 | if (pglen > recvd) | 443 | if (pglen > recvd) |
444 | pglen = recvd; | 444 | pglen = recvd; |
445 | page = rcvbuf->pages; | 445 | page = rcvbuf->pages; |
446 | return nr; | 446 | return pglen; |
447 | } | 447 | } |
448 | 448 | ||
449 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | 449 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index d9a5e832c257..748dc91a4a14 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -555,7 +555,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res | |||
555 | struct page **page; | 555 | struct page **page; |
556 | size_t hdrlen; | 556 | size_t hdrlen; |
557 | u32 recvd, pglen; | 557 | u32 recvd, pglen; |
558 | int status, nr = 0; | 558 | int status; |
559 | 559 | ||
560 | status = ntohl(*p++); | 560 | status = ntohl(*p++); |
561 | /* Decode post_op_attrs */ | 561 | /* Decode post_op_attrs */ |
@@ -586,7 +586,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res | |||
586 | pglen = recvd; | 586 | pglen = recvd; |
587 | page = rcvbuf->pages; | 587 | page = rcvbuf->pages; |
588 | 588 | ||
589 | return nr; | 589 | return pglen; |
590 | } | 590 | } |
591 | 591 | ||
592 | __be32 * | 592 | __be32 * |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0f24cdf2cb13..6a653ffd8e4e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2852,8 +2852,10 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
2852 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); | 2852 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); |
2853 | res.pgbase = args.pgbase; | 2853 | res.pgbase = args.pgbase; |
2854 | status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0); | 2854 | status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0); |
2855 | if (status == 0) | 2855 | if (status >= 0) { |
2856 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); | 2856 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); |
2857 | status += args.pgbase; | ||
2858 | } | ||
2857 | 2859 | ||
2858 | nfs_invalidate_atime(dir); | 2860 | nfs_invalidate_atime(dir); |
2859 | 2861 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index f313c4cce7e4..b7a204ff6fe1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4518,7 +4518,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n | |||
4518 | xdr_read_pages(xdr, pglen); | 4518 | xdr_read_pages(xdr, pglen); |
4519 | 4519 | ||
4520 | 4520 | ||
4521 | return 0; | 4521 | return pglen; |
4522 | } | 4522 | } |
4523 | 4523 | ||
4524 | static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | 4524 | static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) |