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

Commit d5f50b0c authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd4: fix oops on unusual readlike compound



If the argument and reply together exceed the maximum payload size, then
a reply with a read-like operation can overlow the rq_pages array.

Cc: stable@kernel.org
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 9b3234b9
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -2925,11 +2925,16 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
	len = maxcount;
	v = 0;
	while (len > 0) {
		pn = resp->rqstp->rq_resused++;
		pn = resp->rqstp->rq_resused;
		if (!resp->rqstp->rq_respages[pn]) { /* ran out of pages */
			maxcount -= len;
			break;
		}
		resp->rqstp->rq_vec[v].iov_base =
			page_address(resp->rqstp->rq_respages[pn]);
		resp->rqstp->rq_vec[v].iov_len =
			len < PAGE_SIZE ? len : PAGE_SIZE;
		resp->rqstp->rq_resused++;
		v++;
		len -= PAGE_SIZE;
	}
@@ -2975,6 +2980,8 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
		return nfserr;
	if (resp->xbuf->page_len)
		return nfserr_resource;
	if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused])
		return nfserr_resource;

	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);

@@ -3024,6 +3031,8 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
		return nfserr;
	if (resp->xbuf->page_len)
		return nfserr_resource;
	if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused])
		return nfserr_resource;

	RESERVE_SPACE(NFS4_VERIFIER_SIZE);
	savep = p;