callback: handles xdr decode errors

instead of ignoring errors from proc_cb_compound_args(), return NFS4ERR_BADXDR.  note that we still need to allocate the cb_compound_res structure to return this error

added null checks to the end of handle_cb_compound(); if the cb_compound_res allocation fails, we'd crash trying to access res->status and res->resarray_count

also fixed some indenting

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2011-01-10 13:58:55 -05:00
parent 034b2b4ea2
commit 238a8a7015

View file

@ -102,11 +102,11 @@ static enum_t handle_cb_sequence(
} }
/* 20.9.3.: If the difference between csa_sequenceid and the client's /* 20.9.3.: If the difference between csa_sequenceid and the client's
* cachedsequence ID at the slot ID is two (2) or more, or if * cachedsequence ID at the slot ID is two (2) or more, or if
* csa_sequenceid is less than the cached sequence ID (accounting for * csa_sequenceid is less than the cached sequence ID (accounting for
* wraparound of the unsigned sequence ID value), then the client * wraparound of the unsigned sequence ID value), then the client
* MUST return NFS4ERR_SEQ_MISORDERED. * MUST return NFS4ERR_SEQ_MISORDERED.
*/ */
if (args->sequenceid < cb_session->cb_seqnum || if (args->sequenceid < cb_session->cb_seqnum ||
(args->sequenceid - cb_session->cb_seqnum >= 2)) { (args->sequenceid - cb_session->cb_seqnum >= 2)) {
eprintf("[cb] bad received seq#=%d, expected=%d\n", eprintf("[cb] bad received seq#=%d, expected=%d\n",
@ -238,15 +238,12 @@ static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_
XDR *xdr = (XDR*)req->xdr; XDR *xdr = (XDR*)req->xdr;
uint32_t i, status = NFS4_OK; uint32_t i, status = NFS4_OK;
dprintf(CBSLVL, "--> handle_compound()\n"); dprintf(CBSLVL, "--> handle_cb_compound()\n");
/* decode the arguments */ /* decode the arguments */
proc_cb_compound_args(xdr, &args); if (!proc_cb_compound_args(xdr, &args)) {
dprintf(CBSLVL, "CB_COMPOUND('%s', %u)\n", args.tag.str, args.argarray_count); status = NFS4ERR_BADXDR;
if (args.minorversion != 1) { eprintf("failed to decode compound arguments\n");
status = NFS4ERR_MINOR_VERS_MISMATCH; //XXXXX
eprintf("args.minorversion %u != 1\n", args.minorversion);
goto out;
} }
/* allocate the compound results */ /* allocate the compound results */
@ -255,7 +252,7 @@ static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_
status = NFS4ERR_RESOURCE; status = NFS4ERR_RESOURCE;
goto out; goto out;
} }
res->status = NFS4_OK; res->status = status;
StringCchCopyA(res->tag.str, CB_COMPOUND_MAX_TAG, g_server_tag); StringCchCopyA(res->tag.str, CB_COMPOUND_MAX_TAG, g_server_tag);
res->tag.str[CB_COMPOUND_MAX_TAG-1] = 0; res->tag.str[CB_COMPOUND_MAX_TAG-1] = 0;
res->tag.len = (uint32_t)strlen(res->tag.str); res->tag.len = (uint32_t)strlen(res->tag.str);
@ -265,6 +262,13 @@ static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_
goto out; goto out;
} }
dprintf(CBSLVL, "CB_COMPOUND('%s', %u)\n", args.tag.str, args.argarray_count);
if (args.minorversion != 1) {
res->status = NFS4ERR_MINOR_VERS_MISMATCH; //XXXXX
eprintf("args.minorversion %u != 1\n", args.minorversion);
goto out;
}
/* handle each operation in the compound */ /* handle each operation in the compound */
for (i = 0; i < args.argarray_count && res->status == NFS4_OK; i++) { for (i = 0; i < args.argarray_count && res->status == NFS4_OK; i++) {
argop = &args.argarray[i]; argop = &args.argarray[i];
@ -281,8 +285,8 @@ static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_
goto out; goto out;
} }
if (i != 0 && argop->opnum == OP_CB_SEQUENCE) { if (i != 0 && argop->opnum == OP_CB_SEQUENCE) {
res->status = NFS4ERR_SEQUENCE_POS; res->status = NFS4ERR_SEQUENCE_POS;
goto out; goto out;
} }
resop->opnum = argop->opnum; resop->opnum = argop->opnum;
if (status == NFS4ERR_RETRY_UNCACHED_REP) { if (status == NFS4ERR_RETRY_UNCACHED_REP) {
@ -363,8 +367,9 @@ out:
proc_cb_compound_args(xdr, &args); proc_cb_compound_args(xdr, &args);
*reply = res; *reply = res;
dprintf(CBSLVL, "<-- handle_compound() returning %s (%u results)\n", dprintf(CBSLVL, "<-- handle_cb_compound() returning %s (%u results)\n",
nfs_error_string(res->status), res->resarray_count); nfs_error_string(res ? res->status : status),
res ? res->resarray_count : 0);
} }
int nfs41_handle_callback(void *rpc_clnt, void *cb, struct cb_compound_res **reply) int nfs41_handle_callback(void *rpc_clnt, void *cb, struct cb_compound_res **reply)