Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 143b6c40 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

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: default avatarChuck Lever <chuck.lever@oracle.com>
parent 756805e7
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -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),
	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);