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>
This commit is contained in:
parent
756805e7a7
commit
143b6c4008
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue