@@ -246,29 +246,29 @@ nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
}
static __be32
-nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
+nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval,
+ u32 bmlen)
{
- u32 bmlen;
- DECODE_HEAD;
+ __be32 *p;
+ u32 len, i;
- bmval[0] = 0;
- bmval[1] = 0;
- bmval[2] = 0;
+ for (i = 0; i < bmlen; i++)
+ bmval[i] = 0;
- READ_BUF(4);
- bmlen = be32_to_cpup(p++);
- if (bmlen > 1000)
+ if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
+ goto xdr_error;
+ if (len > 1000)
goto xdr_error;
- READ_BUF(bmlen << 2);
- if (bmlen > 0)
- bmval[0] = be32_to_cpup(p++);
- if (bmlen > 1)
- bmval[1] = be32_to_cpup(p++);
- if (bmlen > 2)
- bmval[2] = be32_to_cpup(p++);
+ p = xdr_inline_decode(argp->xdr, len << 2);
+ if (!p)
+ goto xdr_error;
+ for (i = 0; i < len && i < bmlen; i++)
+ bmval[i] = be32_to_cpup(p++);
- DECODE_TAIL;
+ return nfs_ok;
+xdr_error:
+ return nfserr_bad_xdr;
}
static __be32
@@ -282,8 +282,9 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
DECODE_HEAD;
iattr->ia_valid = 0;
- if ((status = nfsd4_decode_bitmap(argp, bmval)))
- return status;
+ status = nfsd4_decode_bitmap4(argp, bmval, 3);
+ if (status)
+ goto out;
if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
|| bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
@@ -665,7 +666,8 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu
static inline __be32
nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
{
- return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
+ return nfsd4_decode_bitmap4(argp, getattr->ga_bmval,
+ ARRAY_SIZE(getattr->ga_bmval));
}
static __be32
@@ -1060,7 +1062,9 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
readdir->rd_dircount = be32_to_cpup(p++);
readdir->rd_maxcount = be32_to_cpup(p++);
- if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
+ status = nfsd4_decode_bitmap4(argp, readdir->rd_bmval,
+ ARRAY_SIZE(readdir->rd_bmval));
+ if (status)
goto out;
DECODE_TAIL;
@@ -1206,7 +1210,9 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
{
DECODE_HEAD;
- if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
+ status = nfsd4_decode_bitmap4(argp, verify->ve_bmval,
+ ARRAY_SIZE(verify->ve_bmval));
+ if (status)
goto out;
/* For convenience's sake, we compare raw xdr'd attributes in
@@ -1285,12 +1291,13 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
break;
case SP4_MACH_CRED:
/* spo_must_enforce */
- status = nfsd4_decode_bitmap(argp,
- exid->spo_must_enforce);
+ status = nfsd4_decode_bitmap4(argp, exid->spo_must_enforce,
+ ARRAY_SIZE(exid->spo_must_enforce));
if (status)
goto out;
/* spo_must_allow */
- status = nfsd4_decode_bitmap(argp, exid->spo_must_allow);
+ status = nfsd4_decode_bitmap4(argp, exid->spo_must_allow,
+ ARRAY_SIZE(exid->spo_must_allow));
if (status)
goto out;
break;
Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- fs/nfsd/nfs4xdr.c | 57 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 25 deletions(-)