diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-08-16 16:03:31 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:16:32 -0400 |
commit | 143b6c4008a7928de7e139c3a77a90e4cad8db2c (patch) | |
tree | 339ee78286645d5e3704772cdf542ff2bc6aedc2 /net/sunrpc | |
parent | 756805e7a76bcd2aae07fe31786fe453375e60b1 (diff) | |
download | lwn-143b6c4008a7928de7e139c3a77a90e4cad8db2c.tar.gz lwn-143b6c4008a7928de7e139c3a77a90e4cad8db2c.zip |
SUNRPC: Fix generation of universal addresses for
Fix some problems with rpcbind v3 and v4 queries from the in-kernel rpcbind
client:
1. The r_addr argument must be a full universal address, not just an IP
address, and
2. The universal address in r_addr is the address of the remote rpcbind
server, not the RPC service being requested
This addresses bugzilla.kernel.org report 8891 for 2.6.23-rc and greater.
In addition, if the rpcbind client is unable to start the rpcbind request,
make sure not to leak the xprt.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 7db75e177e67..0bb6709018de 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -387,6 +387,15 @@ void rpcb_getport_async(struct rpc_task *task) dprintk("RPC: %5u %s: trying rpcbind version %u\n", task->tk_pid, __FUNCTION__, bind_version); + rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, + bind_version, 0); + if (IS_ERR(rpcb_clnt)) { + status = PTR_ERR(rpcb_clnt); + dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", + task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt)); + goto bailout_nofree; + } + map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC); if (!map) { status = -ENOMEM; @@ -401,25 +410,18 @@ void rpcb_getport_async(struct rpc_task *task) map->r_xprt = xprt_get(xprt); map->r_netid = (xprt->prot == IPPROTO_TCP) ? RPCB_NETID_TCP : RPCB_NETID_UDP; - memcpy(&map->r_addr, rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR), - sizeof(map->r_addr)); + memcpy(&map->r_addr, + rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR), + sizeof(map->r_addr)); map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ - rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0); - if (IS_ERR(rpcb_clnt)) { - status = PTR_ERR(rpcb_clnt); - dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", - task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt)); - goto bailout; - } - child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); rpc_release_client(rpcb_clnt); if (IS_ERR(child)) { status = -EIO; dprintk("RPC: %5u %s: rpc_run_task failed\n", task->tk_pid, __FUNCTION__); - goto bailout_nofree; + goto bailout; } rpc_put_task(child); |