summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2020-11-09 16:06:15 -0500
committerTrond Myklebust <trond.myklebust@hammerspace.com>2020-12-02 14:05:53 -0500
commit988998134996a397a47cf758627def5f20dc1e88 (patch)
tree38367b38f786ac0080872f6bc3500dfe9be46682 /fs
parent4aceaaea5eccd32bc40c6c76b262489b2f53ca8d (diff)
downloadlinux-988998134996a397a47cf758627def5f20dc1e88.tar.bz2
pNFS: Clean up open coded xdr string decoding
Use the existing xdr_stream_decode_string_dup() to safely decode into kmalloced strings. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/pnfs_nfs.c43
1 files changed, 7 insertions, 36 deletions
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index 7a97643acf3f..2efcfdd348a1 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -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, '.');