OSDN Git Service

pNFS: Clean up open coded xdr string decoding
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 9 Nov 2020 21:06:15 +0000 (16:06 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 2 Dec 2020 19:05:53 +0000 (14:05 -0500)
Use the existing xdr_stream_decode_string_dup() to safely decode into
kmalloced strings.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/pnfs_nfs.c

index 7a97643..2efcfdd 100644 (file)
@@ -1045,9 +1045,8 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
        struct nfs4_pnfs_ds_addr *da = NULL;
        char *buf, *portstr;
        __be16 port;
-       int nlen, rlen;
+       ssize_t nlen, rlen;
        int tmp[2];
-       __be32 *p;
        char *netid;
        size_t len;
        char *startsep = "";
@@ -1055,45 +1054,17 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
 
 
        /* r_netid */
-       p = xdr_inline_decode(xdr, 4);
-       if (unlikely(!p))
+       nlen = xdr_stream_decode_string_dup(xdr, &netid, XDR_MAX_NETOBJ,
+                                           gfp_flags);
+       if (unlikely(nlen < 0))
                goto out_err;
-       nlen = be32_to_cpup(p++);
-
-       p = xdr_inline_decode(xdr, nlen);
-       if (unlikely(!p))
-               goto out_err;
-
-       netid = kmalloc(nlen+1, gfp_flags);
-       if (unlikely(!netid))
-               goto out_err;
-
-       netid[nlen] = '\0';
-       memcpy(netid, p, nlen);
 
        /* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */
-       p = xdr_inline_decode(xdr, 4);
-       if (unlikely(!p))
-               goto out_free_netid;
-       rlen = be32_to_cpup(p);
-
-       p = xdr_inline_decode(xdr, rlen);
-       if (unlikely(!p))
-               goto out_free_netid;
-
        /* port is ".ABC.DEF", 8 chars max */
-       if (rlen > INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN + 8) {
-               dprintk("%s: Invalid address, length %d\n", __func__,
-                       rlen);
+       rlen = xdr_stream_decode_string_dup(xdr, &buf, INET6_ADDRSTRLEN +
+                                           IPV6_SCOPE_ID_LEN + 8, gfp_flags);
+       if (unlikely(rlen < 0))
                goto out_free_netid;
-       }
-       buf = kmalloc(rlen + 1, gfp_flags);
-       if (!buf) {
-               dprintk("%s: Not enough memory\n", __func__);
-               goto out_free_netid;
-       }
-       buf[rlen] = '\0';
-       memcpy(buf, p, rlen);
 
        /* replace port '.' with '-' */
        portstr = strrchr(buf, '.');