[PATCH RFC] nfsd: prevent hung task in nfsd_nl_listener_set_doit()

"syzbot" <[email protected]>
Newsgroups dev.linux.lists.syzbot
Message-ID <[email protected]>
In nfsd_nl_listener_set_doit(), the kernel iterates over all
NFSD_A_SERVER_SOCK_ADDR attributes provided in a netlink message to
configure NFS server listeners. There is currently no limit on the number
of attributes a user can send.

For each attribute, svc_xprt_create_from_sa() is called, which may
synchronously invoke request_module() to load the corresponding transport
module. If a user provides a large number of invalid transport names,
request_module() is called sequentially for each, taking a massive amount
of time. Since this entire process occurs while holding the global
nfsd_mutex, it blocks other tasks attempting to acquire the mutex and
triggers a hung task timeout:

  INFO: task blocked for more than 10 seconds.
  ...
  Call Trace:
   <TASK>
   __schedule+0x17e7/0x5630 kernel/sched/core.c:7234
   schedule+0x164/0x2b0 kernel/sched/core.c:7326
   schedule_preempt_disabled+0x13/0x30 kernel/sched/core.c:7383
   __mutex_lock_common kernel/locking/mutex.c:726 [inline]
   __mutex_lock+0x7bf/0x1550 kernel/locking/mutex.c:821
   nfsd_nl_version_get_doit+0x17c/0xd20 fs/nfsd/nfsctl.c:1889
   genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
   genl_family_rcv_msg net/netlink/genetlink.c:1194 [inline]
   genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
  ...
  2 locks held by task/5864:
   #0: ffffffff90114168 (cb_lock){++++}-{4:4}, at: genl_rcv+0x19/0x40
   net/netlink/genetlink.c:1217
   #1: ffffffff8eeb1a60 (nfsd_mutex){+.+.}-{4:4}, at:
   nfsd_nl_listener_set_doit+0x135/0x1750 fs/nfsd/nfsctl.c:1964

Furthermore, the function does not break out of the loop if
svc_xprt_create_from_sa() fails, and it suffers from an O(N^2) complexity
issue because svc_find_listener() iterates over the serv->sv_permsocks list
for each attribute.

Address this by introducing a hard limit of 128 NFSD_A_SERVER_SOCK_ADDR
attributes per netlink message. The limit is enforced before acquiring the
nfsd_mutex to prevent lock contention. Additionally, modify the loop to
break immediately if listener creation fails, avoiding needless sequential
request_module() calls for invalid configurations.

Fixes: 16a471177496 ("NFSD: add listener-{set,get} netlink command")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=41bc60511c2884783c27
Link: https://syzkaller.appspot.com/ai_job?id=e7446d8c-5a41-495a-8af7-9f0d7feddff1
To: "Chuck Lever" <[email protected]>
To: "Jeff Layton" <[email protected]>
To: <[email protected]>
To: "Lorenzo Bianconi" <[email protected]>
Cc: "Dai Ngo" <[email protected]>
Cc: <[email protected]>
Cc: "NeilBrown" <[email protected]>
Cc: "Olga Kornievskaia" <[email protected]>
Cc: "Tom Talpey" <[email protected]>

---
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index fa92e31d1..9c1cc02fc 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1960,6 +1960,13 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
 	struct nfsd_net *nn;
 	bool delete = false;
 	int err, rem;
+	int count = 0;
+
+	nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_SOCK_ADDR, info->nlhdr,
+				 GENL_HDRLEN, rem) {
+		if (++count > 128)
+			return -EINVAL;
+	}
 
 	mutex_lock(&nfsd_mutex);
 
@@ -2073,8 +2080,10 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
 		ret = svc_xprt_create_from_sa(serv, xcl_name, net, sa, 0,
 					      current_cred());
 		/* always save the latest error */
-		if (ret < 0)
+		if (ret < 0) {
 			err = ret;
+			break;
+		}
 	}
 
 	if (!serv->sv_nrthreads && list_empty(&nn->nfsd_serv->sv_permsocks))


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 [email protected].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.