[PATCH v3 04/14] SUNRPC: bound the local rpcbind client timeout to 1s

From: Jeff Layton

Date: Fri Aug 28 2026 - 12:39:03 EST


The kernel's local rpcbind client uses the transport defaults: a 10s major
timeout for AF_LOCAL, and 60s for the loopback TCP fallback.
xprt_calc_majortimeo() returns to_initval when to_increment is 0.

Those calls are synchronous, and they run under nfsd_mutex. One operation
makes several of them. rpcb_create_local() tries up to three client
creations, and svc_register() sends one call for each program and version.
A local rpcbind that accepts the connection but never replies stalls every
one of these calls. The accumulated hold is long enough to trip the
hung-task watchdog on other NFSD netlink operations. The holder itself
waits killably and escapes the watchdog:

INFO: task hung in nfsd_nl_cache_flush_doit

The local rpcbind is on loopback or on an AF_LOCAL socket, and it answers
in microseconds. Bound its client to one attempt of 1s.

This shortens the stall. It does not remove the stall, and it is not free.
Registration stays synchronous and stays fatal. An rpcb_create_local()
failure aborts nfsd_create_serv() through svc_bind(), and an
svc_register() failure makes svc_setup_socket() fail. An rpcbind that is
merely slow to be scheduled can therefore now fail server startup, where
it succeeded before. The real fix is to make the registration
asynchronous.

Assisted-by: LLM
Link: https://syzkaller.appspot.com/bug?extid=c7eae0eb80858a2dba0f
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
net/sunrpc/rpcb_clnt.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 6aa372188c86..0aa376b82a52 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -221,6 +221,16 @@ static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
# define SUN_LEN(ptr) (offsetof(struct sockaddr_un, sun_path) \
+ 1 + strlen((ptr)->sun_path + 1))

+/*
+ * The kernel's rpcbind client talks only to the local rpcbind, over loopback
+ * or a local AF_LOCAL socket, where a healthy rpcbind answers in microseconds.
+ */
+static const struct rpc_timeout rpcb_local_timeout = {
+ .to_initval = 1 * HZ,
+ .to_maxval = 1 * HZ,
+ .to_retries = 0,
+};
+
/*
* Returns zero on success, otherwise a negative errno value
* is returned.
@@ -238,6 +248,7 @@ static int rpcb_create_af_local(struct net *net,
.version = RPCBVERS_2,
.authflavor = RPC_AUTH_NULL,
.cred = current_cred(),
+ .timeout = &rpcb_local_timeout,
/*
* We turn off the idle timeout to prevent the kernel
* from automatically disconnecting the socket.
@@ -312,6 +323,7 @@ static int rpcb_create_local_net(struct net *net)
.version = RPCBVERS_2,
.authflavor = RPC_AUTH_UNIX,
.cred = current_cred(),
+ .timeout = &rpcb_local_timeout,
.flags = RPC_CLNT_CREATE_NOPING,
};
struct rpc_clnt *clnt, *clnt4;

--
2.55.0