[SUNRPC] rpcbind requires a privileged port to set portmap data An earlier patch caused rpcbind to use an unprivileged port for both SET and GET requests. SET requests require a privileged port. Test plan: Start up the Linux NFS service. Signed-off-by: Chuck Lever --- net/sunrpc/rpcb_clnt.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -60,7 +60,7 @@ static inline void rpcb_wake_rpcbind_wai rpc_wake_up(&xprt->bindwait); } -static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, int proto, int version) +static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, int proto, int version, int privileged) { struct rpc_create_args args = { .protocol = proto, @@ -70,10 +70,12 @@ static struct rpc_clnt *rpcb_create(char .program = &rpcb_program, .version = version, .authflavor = RPC_AUTH_NULL, - .behavior = (RPC_CLNT_ONESHOT|RPC_CLNT_NOPING|RPC_CLNT_NONPRIVPORT), + .behavior = (RPC_CLNT_ONESHOT|RPC_CLNT_NOPING), }; ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPC_BIND_PORT); + if (!privileged) + args.behavior |= RPC_CLNT_NONPRIVPORT; return rpc_create(&args); } @@ -114,7 +116,7 @@ int rpcb_register(u32 prog, u32 vers, in sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin, - IPPROTO_UDP, 2); + IPPROTO_UDP, 2, 1); if (IS_ERR(rpcb_clnt)) return PTR_ERR(rpcb_clnt); @@ -158,7 +160,7 @@ int rpcb_getport_external(struct sockadd NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr)); - rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2); + rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0); if (IS_ERR(rpcb_clnt)) return PTR_ERR(rpcb_clnt); @@ -237,7 +239,7 @@ void rpcb_getport(struct rpc_task *task, rpc_peeraddr(clnt, (void *) &addr, sizeof(addr)); rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR, map->r_addr, sizeof(map->r_addr)); - rpcb_clnt = rpcb_create(clnt->cl_server, &addr, protocol, bind_version); + rpcb_clnt = rpcb_create(clnt->cl_server, &addr, protocol, bind_version, 0); if (IS_ERR(rpcb_clnt)) { rpc_exit(task, PTR_ERR(rpcb_clnt)); dprintk("RPC: %5u rpcb_getport rpcb_create failed, error %ld\n",