summaryrefslogtreecommitdiff
path: root/net/sunrpc/rpcb_clnt.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-09-11 18:00:31 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-09 17:16:48 -0400
commite65fe3976f594603ed7b1b4a99d3e9b867f573ea (patch)
treebacc7a15719862f3d9dd9441451dc80edad57afb /net/sunrpc/rpcb_clnt.c
parentd66968f207b6402fd12c20145cb31dbe3608979c (diff)
downloadlwn-e65fe3976f594603ed7b1b4a99d3e9b867f573ea.tar.gz
lwn-e65fe3976f594603ed7b1b4a99d3e9b867f573ea.zip
SUNRPC: Make rpcb_decode_getaddr more picky about universal addresses
Add better sanity checking of server replies to the GETVERSADDR reply decoder. Change the error return code: EIO is what other XDR decoding routines return if there is a failure while decoding. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpcb_clnt.c')
-rw-r--r--net/sunrpc/rpcb_clnt.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index f88ab90b8d34..34738c5cf312 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -528,12 +528,19 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
*portp = 0;
addr_len = ntohl(*p++);
- if (addr_len > RPCB_MAXADDRLEN) /* sanity */
- return -EINVAL;
-
- dprintk("RPC: rpcb_decode_getaddr returned string: '%s'\n",
- (char *) p);
+ /*
+ * Simple sanity check. The smallest possible universal
+ * address is an IPv4 address string containing 11 bytes.
+ */
+ if (addr_len < 11 || addr_len > RPCB_MAXADDRLEN)
+ goto out_err;
+
+ /*
+ * Start at the end and walk backwards until the first dot
+ * is encountered. When the second dot is found, we have
+ * both parts of the port number.
+ */
addr = (char *)p;
val = 0;
first = 1;
@@ -555,8 +562,19 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
}
}
+ /*
+ * Simple sanity check. If we never saw a dot in the reply,
+ * then this was probably just garbage.
+ */
+ if (first)
+ goto out_err;
+
dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp);
return 0;
+
+out_err:
+ dprintk("RPC: rpcbind server returned malformed reply\n");
+ return -EIO;
}
#define RPCB_program_sz (1u)