NFSD: Replace READ* macros in nfsd4_decode_create()
authorChuck Lever <chuck.lever@oracle.com>
Tue, 3 Nov 2020 18:24:10 +0000 (13:24 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 30 Nov 2020 19:46:37 +0000 (14:46 -0500)
A dedicated decoder for component4 is introduced here, which will be
used by other operation decoders in subsequent patches.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4xdr.c

index 1807693..85283b5 100644 (file)
@@ -92,6 +92,8 @@ check_filename(char *str, int len)
 
        if (len == 0)
                return nfserr_inval;
+       if (len > NFS4_MAXNAMLEN)
+               return nfserr_nametoolong;
        if (isdotent(str, len))
                return nfserr_badname;
        for (i = 0; i < len; i++)
@@ -206,6 +208,27 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 }
 
 static __be32
+nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
+{
+       __be32 *p, status;
+
+       if (xdr_stream_decode_u32(argp->xdr, lenp) < 0)
+               return nfserr_bad_xdr;
+       p = xdr_inline_decode(argp->xdr, *lenp);
+       if (!p)
+               return nfserr_bad_xdr;
+       status = check_filename((char *)p, *lenp);
+       if (status)
+               return status;
+       *namp = svcxdr_tmpalloc(argp, *lenp);
+       if (!*namp)
+               return nfserr_jukebox;
+       memcpy(*namp, p, *lenp);
+
+       return nfs_ok;
+}
+
+static __be32
 nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 {
        DECODE_HEAD;
@@ -698,24 +721,27 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit
 static __be32
 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 {
-       DECODE_HEAD;
+       __be32 *p, status;
 
-       READ_BUF(4);
-       create->cr_type = be32_to_cpup(p++);
+       if (xdr_stream_decode_u32(argp->xdr, &create->cr_type) < 0)
+               return nfserr_bad_xdr;
        switch (create->cr_type) {
        case NF4LNK:
-               READ_BUF(4);
-               create->cr_datalen = be32_to_cpup(p++);
-               READ_BUF(create->cr_datalen);
+               if (xdr_stream_decode_u32(argp->xdr, &create->cr_datalen) < 0)
+                       return nfserr_bad_xdr;
+               p = xdr_inline_decode(argp->xdr, create->cr_datalen);
+               if (!p)
+                       return nfserr_bad_xdr;
                create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
                if (!create->cr_data)
                        return nfserr_jukebox;
                break;
        case NF4BLK:
        case NF4CHR:
-               READ_BUF(8);
-               create->cr_specdata1 = be32_to_cpup(p++);
-               create->cr_specdata2 = be32_to_cpup(p++);
+               if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata1) < 0)
+                       return nfserr_bad_xdr;
+               if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata2) < 0)
+                       return nfserr_bad_xdr;
                break;
        case NF4SOCK:
        case NF4FIFO:
@@ -723,22 +749,18 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
        default:
                break;
        }
-
-       READ_BUF(4);
-       create->cr_namelen = be32_to_cpup(p++);
-       READ_BUF(create->cr_namelen);
-       SAVEMEM(create->cr_name, create->cr_namelen);
-       if ((status = check_filename(create->cr_name, create->cr_namelen)))
+       status = nfsd4_decode_component4(argp, &create->cr_name,
+                                        &create->cr_namelen);
+       if (status)
                return status;
-
        status = nfsd4_decode_fattr4(argp, create->cr_bmval,
                                    ARRAY_SIZE(create->cr_bmval),
                                    &create->cr_iattr, &create->cr_acl,
                                    &create->cr_label, &create->cr_umask);
        if (status)
-               goto out;
+               return status;
 
-       DECODE_TAIL;
+       return nfs_ok;
 }
 
 static inline __be32