All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] SUNRPC: Add a short timeout for local rpcbind calls to prevent DoS
@ 2026-08-07 18:45 syzbot
  0 siblings, 0 replies; only message in thread
From: syzbot @ 2026-08-07 18:45 UTC (permalink / raw)
  To: syzkaller-upstream-moderation; +Cc: syzbot

A local denial-of-service (DoS) vulnerability can be triggered by holding
the global nfsd_mutex while making a synchronous RPC call to the local
rpcbind daemon, which can be maliciously tarpitted.

When nfsd_nl_listener_set_doit() is called to modify listeners, it acquires
nfsd_mutex and destroys existing listeners. For each destroyed listener,
svc_delete_xprt() attempts to unregister the port from the local rpcbind by
calling svc_register(). This function iterates over all registered RPC
programs and versions, making a synchronous rpcb_register_call() for each
combination.

An attacker can run in a new network namespace, mount a tmpfs over /run to
hide the rpcbind UNIX sockets, and bind a fake rpcbind server to
127.0.0.1:111. When the kernel connects and sends the unregister request,
the fake server accepts the connection but intentionally sleeps without
replying. Since the local rpcbind client inherits the default 60-second TCP
RPC timeout, the thread holding nfsd_mutex blocks for a long time. Other
threads attempting to acquire the mutex will block, eventually triggering
the hung task watchdog and crashing the system:

INFO: task blocked for more than 15 seconds.
Call Trace:
 <TASK>
 __schedule+0x17d9/0x56c0 kernel/sched/core.c:7234
 schedule+0x164/0x2b0 kernel/sched/core.c:7326
 __mutex_lock+0x7bf/0x1550 kernel/locking/mutex.c:821
 nfsd_nl_threads_get_doit+0x1c0/0x790 fs/nfsd/nfsctl.c:1754
 genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
 genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
 netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556
 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
 netlink_unicast+0x7bb/0x940 net/netlink/af_netlink.c:1345
 netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900

To fix this, local IPC should not be allowed to block for long periods.
Introduce a short 100ms timeout for local rpcbind clients. Add the
RPC_TASK_SOFT and RPC_TASK_TIMEOUT flags to rpcb_register_call() to ensure
the RPC call returns -ETIMEDOUT when the timeout expires. Finally,
propagate the -ETIMEDOUT error through svc_generic_rpcbind_set() and abort
the outer loop in svc_register() early, preventing multiple timeouts from
accumulating and exceeding the hung task watchdog limit.

Fixes: 2a76b3bfa229 ("SUNRPC: Use TCP for local rpcbind upcalls")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+c0831b61d6ade1e2d098@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c0831b61d6ade1e2d098
Link: https://syzkaller.appspot.com/ai_job?id=baf7f685-d9f6-4911-b692-3b89801723c0
To: "Anna Schumaker" <anna@kernel.org>
To: "Chuck Lever" <cel@kernel.org>
To: "David S. Miller" <davem@davemloft.net>
To: "Eric Dumazet" <edumazet@google.com>
To: "Jeff Layton" <jlayton@kernel.org>
To: "Jakub Kicinski" <kuba@kernel.org>
To: <linux-nfs@vger.kernel.org>
To: <netdev@vger.kernel.org>
To: "Paolo Abeni" <pabeni@redhat.com>
To: "Trond Myklebust" <trondmy@kernel.org>
To: "Chuck Lever" <chuck.lever@oracle.com>
Cc: "Dai Ngo" <Dai.Ngo@oracle.com>
Cc: "Simon Horman" <horms@kernel.org>
Cc: <linux-kernel@vger.kernel.org>
Cc: "NeilBrown" <neil@brown.name>
Cc: "Olga Kornievskaia" <okorniev@redhat.com>
Cc: "Tom Talpey" <tom@talpey.com>

---
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 6aa372188..4094f3257 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -221,6 +221,12 @@ 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))
 
+static const struct rpc_timeout rpcb_local_timeout = {
+	.to_initval = (HZ / 10) ? : 1,
+	.to_maxval = (HZ / 10) ? : 1,
+	.to_retries = 0,
+};
+
 /*
  * Returns zero on success, otherwise a negative errno value
  * is returned.
@@ -238,6 +244,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 +319,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;
@@ -402,11 +410,11 @@ static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename,
 
 static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set)
 {
-	int flags = RPC_TASK_NOCONNECT;
+	int flags = RPC_TASK_NOCONNECT | RPC_TASK_SOFT | RPC_TASK_TIMEOUT;
 	int error, result = 0;
 
 	if (is_set || !sn->rpcb_is_af_local)
-		flags = RPC_TASK_SOFTCONN;
+		flags |= RPC_TASK_SOFTCONN;
 	msg->rpc_resp = &result;
 
 	error = rpc_call_sync(clnt, msg, flags);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index ae9ec4bf3..539ddd064 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1207,6 +1207,9 @@ int svc_generic_rpcbind_set(struct net *net,
 	error = svc_rpcbind_set_version(net, progp, version,
 					family, proto, port);
 
+	if (error == -ETIMEDOUT)
+		return error;
+
 	return (vers->vs_rpcb_optnl) ? 0 : error;
 }
 EXPORT_SYMBOL_GPL(svc_generic_rpcbind_set);
@@ -1243,6 +1246,8 @@ int svc_register(const struct svc_serv *serv, struct net *net,
 				printk(KERN_WARNING "svc: failed to register "
 					"%sv%u RPC service (errno %d).\n",
 					progp->pg_name, i, -error);
+				if (error == -ETIMEDOUT)
+					return error;
 				break;
 			}
 		}


base-commit: 075b74841bd0065a3bda3440873c747938e69b68
-- 
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).

See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
The person who has signed off on the patch is responsible for
addressing comments.
syzbot engineers can be reached at syzkaller@googlegroups.com.

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-07 18:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07 18:45 [PATCH RFC] SUNRPC: Add a short timeout for local rpcbind calls to prevent DoS syzbot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.