NFS: readdir shouldn't read beyond the reply returned by the server
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
8cd51a0ccd
commit
ac39612824
5 changed files with 11 additions and 7 deletions
|
@ -573,11 +573,13 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
|
||||||
if (!pages_ptr)
|
if (!pages_ptr)
|
||||||
goto out_release_array;
|
goto out_release_array;
|
||||||
do {
|
do {
|
||||||
|
unsigned int pglen;
|
||||||
status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
|
status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
break;
|
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 < 0) {
|
||||||
if (status == -ENOSPC)
|
if (status == -ENOSPC)
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
|
@ -423,7 +423,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
|
||||||
struct page **page;
|
struct page **page;
|
||||||
size_t hdrlen;
|
size_t hdrlen;
|
||||||
unsigned int pglen, recvd;
|
unsigned int pglen, recvd;
|
||||||
int status, nr = 0;
|
int status;
|
||||||
|
|
||||||
if ((status = ntohl(*p++)))
|
if ((status = ntohl(*p++)))
|
||||||
return nfs_stat_to_errno(status);
|
return nfs_stat_to_errno(status);
|
||||||
|
@ -443,7 +443,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
|
||||||
if (pglen > recvd)
|
if (pglen > recvd)
|
||||||
pglen = recvd;
|
pglen = recvd;
|
||||||
page = rcvbuf->pages;
|
page = rcvbuf->pages;
|
||||||
return nr;
|
return pglen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
|
static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
|
||||||
|
|
|
@ -555,7 +555,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
|
||||||
struct page **page;
|
struct page **page;
|
||||||
size_t hdrlen;
|
size_t hdrlen;
|
||||||
u32 recvd, pglen;
|
u32 recvd, pglen;
|
||||||
int status, nr = 0;
|
int status;
|
||||||
|
|
||||||
status = ntohl(*p++);
|
status = ntohl(*p++);
|
||||||
/* Decode post_op_attrs */
|
/* Decode post_op_attrs */
|
||||||
|
@ -586,7 +586,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
|
||||||
pglen = recvd;
|
pglen = recvd;
|
||||||
page = rcvbuf->pages;
|
page = rcvbuf->pages;
|
||||||
|
|
||||||
return nr;
|
return pglen;
|
||||||
}
|
}
|
||||||
|
|
||||||
__be32 *
|
__be32 *
|
||||||
|
|
|
@ -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);
|
nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
|
||||||
res.pgbase = args.pgbase;
|
res.pgbase = args.pgbase;
|
||||||
status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
|
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);
|
memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
|
||||||
|
status += args.pgbase;
|
||||||
|
}
|
||||||
|
|
||||||
nfs_invalidate_atime(dir);
|
nfs_invalidate_atime(dir);
|
||||||
|
|
||||||
|
|
|
@ -4518,7 +4518,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
|
||||||
xdr_read_pages(xdr, pglen);
|
xdr_read_pages(xdr, pglen);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return pglen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
|
static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
|
||||||
|
|
Loading…
Add table
Reference in a new issue