@@ -570,24 +570,22 @@ nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
{
- DECODE_HEAD;
struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
- u32 dummy, uid, gid;
+ u32 dummy, uid, gid, i, nr_secflavs;
char *machine_name;
- int i;
- int nr_secflavs;
+ __be32 *p;
/* callback_sec_params4 */
- READ_BUF(4);
- nr_secflavs = be32_to_cpup(p++);
+ if (xdr_stream_decode_u32(argp->xdr, &nr_secflavs) < 0)
+ goto xdr_error;
if (nr_secflavs)
cbs->flavor = (u32)(-1);
else
/* Is this legal? Be generous, take it to mean AUTH_NONE: */
cbs->flavor = 0;
for (i = 0; i < nr_secflavs; ++i) {
- READ_BUF(4);
- dummy = be32_to_cpup(p++);
+ if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+ goto xdr_error;
switch (dummy) {
case RPC_AUTH_NULL:
/* Nothing to read */
@@ -595,24 +593,32 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
cbs->flavor = RPC_AUTH_NULL;
break;
case RPC_AUTH_UNIX:
- READ_BUF(8);
/* stamp */
- dummy = be32_to_cpup(p++);
+ if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+ goto xdr_error;
/* machine name */
- dummy = be32_to_cpup(p++);
- READ_BUF(dummy);
- SAVEMEM(machine_name, dummy);
+ if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+ goto xdr_error;
+ p = xdr_inline_decode(argp->xdr, dummy);
+ if (!p)
+ goto xdr_error;
+ machine_name = svcxdr_tmpalloc(argp, dummy);
+ if (!machine_name)
+ goto nomem;
+ memcpy(machine_name, p, dummy);
- /* uid, gid */
- READ_BUF(8);
+ /* uid, gid, gidcount */
+ p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 3);
+ if (!p)
+ goto xdr_error;
uid = be32_to_cpup(p++);
gid = be32_to_cpup(p++);
- /* more gids */
- READ_BUF(4);
- dummy = be32_to_cpup(p++);
- READ_BUF(dummy * 4);
+ dummy = be32_to_cpup(p);
+ p = xdr_inline_decode(argp->xdr, dummy << 2);
+ if (!p)
+ goto xdr_error;
if (cbs->flavor == (u32)(-1)) {
kuid_t kuid = make_kuid(userns, uid);
kgid_t kgid = make_kgid(userns, gid);
@@ -629,26 +635,37 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
case RPC_AUTH_GSS:
dprintk("RPC_AUTH_GSS callback secflavor "
"not supported!\n");
- READ_BUF(8);
+
/* gcbp_service */
- dummy = be32_to_cpup(p++);
+ if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+ goto xdr_error;
+
/* gcbp_handle_from_server */
- dummy = be32_to_cpup(p++);
- READ_BUF(dummy);
- p += XDR_QUADLEN(dummy);
+ if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+ goto xdr_error;
+ if (!xdr_inline_decode(argp->xdr, dummy))
+ goto xdr_error;
+
/* gcbp_handle_from_client */
- READ_BUF(4);
- dummy = be32_to_cpup(p++);
- READ_BUF(dummy);
+ if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+ goto xdr_error;
+ if (!xdr_inline_decode(argp->xdr, dummy))
+ goto xdr_error;
break;
default:
dprintk("Illegal callback secflavor\n");
return nfserr_inval;
}
}
- DECODE_TAIL;
+
+ return nfs_ok;
+xdr_error:
+ return nfserr_bad_xdr;
+nomem:
+ return nfserr_jukebox;
}
+
/*
* NFSv4 operation argument decoders
*/
Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- fs/nfsd/nfs4xdr.c | 73 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 28 deletions(-)