diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-09-12 02:00:31 +0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-10 01:16:48 +0400 |
commit | e65fe3976f594603ed7b1b4a99d3e9b867f573ea (patch) | |
tree | bacc7a15719862f3d9dd9441451dc80edad57afb /net/sunrpc/rpcb_clnt.c | |
parent | d66968f207b6402fd12c20145cb31dbe3608979c (diff) | |
download | linux-e65fe3976f594603ed7b1b4a99d3e9b867f573ea.tar.xz |
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.c | 28 |
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) |