Skip to content

Commit d5f50b0

Browse files
author
J. Bruce Fields
committed
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: [email protected] Signed-off-by: J. Bruce Fields <[email protected]>
1 parent 9b3234b commit d5f50b0

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

fs/nfsd/nfs4xdr.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2925,11 +2925,16 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
29252925
len = maxcount;
29262926
v = 0;
29272927
while (len > 0) {
2928-
pn = resp->rqstp->rq_resused++;
2928+
pn = resp->rqstp->rq_resused;
2929+
if (!resp->rqstp->rq_respages[pn]) { /* ran out of pages */
2930+
maxcount -= len;
2931+
break;
2932+
}
29292933
resp->rqstp->rq_vec[v].iov_base =
29302934
page_address(resp->rqstp->rq_respages[pn]);
29312935
resp->rqstp->rq_vec[v].iov_len =
29322936
len < PAGE_SIZE ? len : PAGE_SIZE;
2937+
resp->rqstp->rq_resused++;
29332938
v++;
29342939
len -= PAGE_SIZE;
29352940
}
@@ -2975,6 +2980,8 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
29752980
return nfserr;
29762981
if (resp->xbuf->page_len)
29772982
return nfserr_resource;
2983+
if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused])
2984+
return nfserr_resource;
29782985

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

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

30283037
RESERVE_SPACE(NFS4_VERIFIER_SIZE);
30293038
savep = p;

0 commit comments

Comments
 (0)