@@ -222,11 +222,13 @@ static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_ne
p = xdr_inline_decode(argp->xdr, len);
if (!p)
goto xdr_error;
- o->data = svcxdr_tmpalloc(argp, len);
- if (!o->data)
- goto nomem;
- o->len = len;
- memcpy(o->data, p, len);
+ if (o) {
+ o->data = svcxdr_tmpalloc(argp, len);
+ if (!o->data)
+ goto nomem;
+ o->len = len;
+ memcpy(o->data, p, len);
+ }
return nfs_ok;
xdr_error:
@@ -1482,13 +1484,56 @@ static __be32 nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
return nfsd4_decode_bitmap4(argp, must_allow, ma_len);
}
+/*
+ * This implementation currently does not support SP4_SSV.
+ * This decoder simply skips over these arguments.
+ */
+static __be32 nfsd4_decode_ssv_sp_parms(struct nfsd4_compoundargs *argp)
+{
+ u32 bm[3], count;
+ __be32 status;
+
+ /* ssp_ops */
+ status = nfsd4_decode_state_protect_ops(argp, bm, ARRAY_SIZE(bm),
+ bm, ARRAY_SIZE(bm));
+ if (status)
+ goto out;
+
+ /* ssp_hash_algs<> */
+ if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+ goto xdr_error;
+ while (count--) {
+ status = nfsd4_decode_opaque(argp, NULL);
+ if (status)
+ goto out;
+ }
+
+ /* ssp_encr_algs<> */
+ if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+ goto xdr_error;
+ while (count--) {
+ status = nfsd4_decode_opaque(argp, NULL);
+ if (status)
+ goto out;
+ }
+
+ /* ssp_window and ssp_num_gss_handles are ignored */
+ if (!xdr_inline_decode(argp->xdr, sizeof(__be32) * 2))
+ goto xdr_error;
+
+ status = nfs_ok;
+out:
+ return status;
+xdr_error:
+ return nfserr_bad_xdr;
+}
+
static __be32
nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
struct nfsd4_exchange_id *exid)
{
- int dummy, tmp;
DECODE_HEAD;
- u32 bm[3];
+ int dummy;
READ_BUF(NFS4_VERIFIER_SIZE);
COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
@@ -1516,34 +1561,9 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
goto out;
break;
case SP4_SSV:
- /* ssp_ops */
- status = nfsd4_decode_state_protect_ops(argp, bm, ARRAY_SIZE(bm),
- bm, ARRAY_SIZE(bm));
+ status = nfsd4_decode_ssv_sp_parms(argp);
if (status)
goto out;
-
- /* ssp_hash_algs<> */
- READ_BUF(4);
- tmp = be32_to_cpup(p++);
- while (tmp--) {
- READ_BUF(4);
- dummy = be32_to_cpup(p++);
- READ_BUF(dummy);
- p += XDR_QUADLEN(dummy);
- }
-
- /* ssp_encr_algs<> */
- READ_BUF(4);
- tmp = be32_to_cpup(p++);
- while (tmp--) {
- READ_BUF(4);
- dummy = be32_to_cpup(p++);
- READ_BUF(dummy);
- p += XDR_QUADLEN(dummy);
- }
-
- /* ignore ssp_window and ssp_num_gss_handles: */
- READ_BUF(8);
break;
default:
goto xdr_error;
Refactor for clarity. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- fs/nfsd/nfs4xdr.c | 86 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 33 deletions(-)