diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-09-11 18:00:31 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:16:48 -0400 |
commit | e65fe3976f594603ed7b1b4a99d3e9b867f573ea (patch) | |
tree | bacc7a15719862f3d9dd9441451dc80edad57afb /net | |
parent | d66968f207b6402fd12c20145cb31dbe3608979c (diff) |
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')
-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, | |||
528 | 528 | ||
529 | *portp = 0; | 529 | *portp = 0; |
530 | addr_len = ntohl(*p++); | 530 | addr_len = ntohl(*p++); |
531 | if (addr_len > RPCB_MAXADDRLEN) /* sanity */ | ||
532 | return -EINVAL; | ||
533 | |||
534 | dprintk("RPC: rpcb_decode_getaddr returned string: '%s'\n", | ||
535 | (char *) p); | ||
536 | 531 | ||
532 | /* | ||
533 | * Simple sanity check. The smallest possible universal | ||
534 | * address is an IPv4 address string containing 11 bytes. | ||
535 | */ | ||
536 | if (addr_len < 11 || addr_len > RPCB_MAXADDRLEN) | ||
537 | goto out_err; | ||
538 | |||
539 | /* | ||
540 | * Start at the end and walk backwards until the first dot | ||
541 | * is encountered. When the second dot is found, we have | ||
542 | * both parts of the port number. | ||
543 | */ | ||
537 | addr = (char *)p; | 544 | addr = (char *)p; |
538 | val = 0; | 545 | val = 0; |
539 | first = 1; | 546 | first = 1; |
@@ -555,8 +562,19 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p, | |||
555 | } | 562 | } |
556 | } | 563 | } |
557 | 564 | ||
565 | /* | ||
566 | * Simple sanity check. If we never saw a dot in the reply, | ||
567 | * then this was probably just garbage. | ||
568 | */ | ||
569 | if (first) | ||
570 | goto out_err; | ||
571 | |||
558 | dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp); | 572 | dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp); |
559 | return 0; | 573 | return 0; |
574 | |||
575 | out_err: | ||
576 | dprintk("RPC: rpcbind server returned malformed reply\n"); | ||
577 | return -EIO; | ||
560 | } | 578 | } |
561 | 579 | ||
562 | #define RPCB_program_sz (1u) | 580 | #define RPCB_program_sz (1u) |