Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> --- fs/nfsd/nfs4xdr.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 6897078bde82..dfd2008db299 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1617,15 +1617,20 @@ static __be32 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, struct nfsd4_create_session *sess) { - DECODE_HEAD; + __be32 *p, status; - READ_BUF(16); - COPYMEM(&sess->clientid, 8); - sess->seqid = be32_to_cpup(p++); - sess->flags = be32_to_cpup(p++); + status = nfsd4_decode_clientid4(argp, &sess->clientid); + if (status) + goto out; + if (xdr_stream_decode_u32(argp->xdr, &sess->seqid) < 0) + goto xdr_error; + if (xdr_stream_decode_u32(argp->xdr, &sess->flags) < 0) + goto xdr_error; /* Fore channel attrs */ - READ_BUF(28); + p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 7); + if (!p) + goto xdr_error; p++; /* headerpadsz is always 0 */ sess->fore_channel.maxreq_sz = be32_to_cpup(p++); sess->fore_channel.maxresp_sz = be32_to_cpup(p++); @@ -1634,15 +1639,17 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, sess->fore_channel.maxreqs = be32_to_cpup(p++); sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++); if (sess->fore_channel.nr_rdma_attrs == 1) { - READ_BUF(4); - sess->fore_channel.rdma_attrs = be32_to_cpup(p++); + if (xdr_stream_decode_u32(argp->xdr, &sess->fore_channel.rdma_attrs) < 0) + goto xdr_error; } else if (sess->fore_channel.nr_rdma_attrs > 1) { dprintk("Too many fore channel attr bitmaps!\n"); goto xdr_error; } /* Back channel attrs */ - READ_BUF(28); + p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 7); + if (!p) + goto xdr_error; p++; /* headerpadsz is always 0 */ sess->back_channel.maxreq_sz = be32_to_cpup(p++); sess->back_channel.maxresp_sz = be32_to_cpup(p++); @@ -1651,17 +1658,24 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, sess->back_channel.maxreqs = be32_to_cpup(p++); sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++); if (sess->back_channel.nr_rdma_attrs == 1) { - READ_BUF(4); - sess->back_channel.rdma_attrs = be32_to_cpup(p++); + if (xdr_stream_decode_u32(argp->xdr, &sess->back_channel.rdma_attrs) < 0) + goto xdr_error; } else if (sess->back_channel.nr_rdma_attrs > 1) { dprintk("Too many back channel attr bitmaps!\n"); goto xdr_error; } - READ_BUF(4); - sess->callback_prog = be32_to_cpup(p++); - nfsd4_decode_cb_sec(argp, &sess->cb_sec); - DECODE_TAIL; + if (xdr_stream_decode_u32(argp->xdr, &sess->callback_prog) < 0) + goto xdr_error; + status = nfsd4_decode_cb_sec(argp, &sess->cb_sec); + if (status) + goto out; + + status = nfs_ok; +out: + return nfs_ok; +xdr_error: + return nfserr_bad_xdr; } static __be32