[ 048/123] nfsd4: fix oops on unusual readlike compound
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: 2013-01-09 20:38:57
Also in:
lkml
3.7-stable review patch. If anyone has any objections, please let me know. ------------------ From: "J. Bruce Fields" <redacted> commit d5f50b0c290431c65377c4afa1c764e2c3fe5305 upstream. 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. Signed-off-by: J. Bruce Fields <redacted> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- fs/nfsd/nfs4xdr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c@@ -2946,11 +2946,16 @@ nfsd4_encode_read(struct nfsd4_compoundr 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; }
@@ -2996,6 +3001,8 @@ nfsd4_encode_readlink(struct nfsd4_compo 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++]);
@@ -3045,6 +3052,8 @@ nfsd4_encode_readdir(struct nfsd4_compou 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;