Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac396128 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: readdir shouldn't read beyond the reply returned by the server

parent 8cd51a0c
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -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;
+2 −2
Original line number Original line Diff line number Diff line
@@ -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)
+2 −2
Original line number Original line Diff line number Diff line
@@ -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 *
+3 −1
Original line number Original line Diff line number Diff line
@@ -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);


+1 −1
Original line number Original line Diff line number Diff line
@@ -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)