NetBSD Problem Report #58297

From www@netbsd.org  Tue May 28 21:42:49 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id CEC021A923A
	for <gnats-bugs@gnats.NetBSD.org>; Tue, 28 May 2024 21:42:49 +0000 (UTC)
Message-Id: <20240528214248.8C9791A923C@mollari.NetBSD.org>
Date: Tue, 28 May 2024 21:42:48 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: net/nd.c leaks mbufs pending neighbour discovery
X-Send-Pr-Version: www-1.0

>Number:         58297
>Category:       kern
>Synopsis:       net/nd.c leaks mbufs pending neighbour discovery
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 28 21:45:01 +0000 2024
>Closed-Date:    Thu Sep 12 13:23:54 +0000 2024
>Last-Modified:  Thu Sep 12 13:23:54 +0000 2024
>Originator:     Taylor R Campbell
>Release:        current, 10
>Organization:
The NDBSD Foundation
>Environment:
>Description:
When the network stack needs the link-layer address of the next hop for an outgoing packet, it asks nd_resolve (e.g., via ether_output -> arpresolve).

If nd_resolve doesn't know the link-layer address, it queues up the packet's mbuf in struct llentry::la_hold (a.k.a. ln_hold) for all packets to be transmitted via the same next hop once the link-layer address is resolved (via arp, ipv6nd, ...).  (If the queue exceeds a maximum length -- currently, always 1 -- then older packets are freed.)

From time to time, the still-pending packets are supposed to be freed in lltable_drop_entry_queue, via lltable_drain (from arp_drain, called by arp_fasttimo; XXX no IPv6 callers?) or via llentry_free (from lltable_purge_entries, called by in_if_down, in6_if_down, nd6_purge).

But lltable_drop_entry_queue only frees the queued mbufs if la_numheld is positive.  And nothing ever increments la_numheld.  So whenever an llentry is freed, e.g. when an interface is brought down, it will leak any queued mbufs waiting for their next hop's link-layer address resolution.

Found by Edgar Fuss: https://mail-index.netbsd.org/tech-net/2024/04/23/msg008762.html
>How-To-Repeat:
1. ping a host on the local network that doesn't exist
2. bring the interface down before link-layer resolution has timed out and given up
>Fix:
From 2786a8a8ed3b3223888c8374c5d32162866aec91 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Wed, 24 Apr 2024 14:08:35 +0000
Subject: [PATCH] nd_resolve: Maintain la_numheld.

Otherwise lltable_drop_entry_quene never drops anything.

Addresses mbuf leak, PR kern/XXXXX.
---
 sys/net/nd.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/sys/net/nd.c b/sys/net/nd.c
index c9c2ca6fddec..7be385b74693 100644
--- a/sys/net/nd.c
+++ b/sys/net/nd.c
@@ -374,14 +374,25 @@ nd_resolve(struct llentry *ln, const struct rtentry *rt, struct mbuf *m,
 				break;
 			}
 		}
+		KASSERTMSG(ln->la_numheld == i, "la_numheld=%d i=%d",
+		    ln->la_numheld, i);
 		while (i >= nd->nd_maxqueuelen) {
 			m_hold = ln->ln_hold;
 			ln->ln_hold = ln->ln_hold->m_nextpkt;
 			m_freem(m_hold);
 			i--;
+			ln->la_numheld--;
 		}
-	} else
+	} else {
+		KASSERTMSG(ln->la_numheld == 0, "la_numheld=%d",
+		    ln->la_numheld);
 		ln->ln_hold = m;
+	}
+
+	KASSERTMSG(ln->la_numheld < nd->nd_maxqueuelen,
+	    "la_numheld=%d nd_maxqueuelen=%d",
+	    ln->la_numheld, nd->nd_maxqueuelen);
+	ln->la_numheld++;

 	if (ln->ln_asked >= nd->nd_mmaxtries)
 		error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ?

>Release-Note:

>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58297 CVS commit: src/sys/net
Date: Tue, 28 May 2024 22:15:22 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Tue May 28 22:15:22 UTC 2024

 Modified Files:
 	src/sys/net: nd.c

 Log Message:
 nd_resolve: Maintain la_numheld.

 Otherwise lltable_drop_entry_queue never drops anything.

 Addresses mbuf leak, PR kern/58297.


 To generate a diff of this commit:
 cvs rdiff -u -r1.5 -r1.6 src/sys/net/nd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58297 CVS commit: src/sys/net
Date: Thu, 30 May 2024 23:00:40 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu May 30 23:00:39 UTC 2024

 Modified Files:
 	src/sys/net: nd.c

 Log Message:
 nd_timer: Update la_numheld when we clear la_hold (a.k.a. ln_hold).

 Followup for PR kern/58297 fix.  Patch by mlelstv@.

 PR kern/58301


 To generate a diff of this commit:
 cvs rdiff -u -r1.6 -r1.7 src/sys/net/nd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->needs-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Tue, 23 Jul 2024 21:08:03 +0000
State-Changed-Why:
needs pullup-10, but I think this code was new since 9


From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58297 CVS commit: [netbsd-10] src/sys/net
Date: Wed, 11 Sep 2024 16:18:36 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Wed Sep 11 16:18:36 UTC 2024

 Modified Files:
 	src/sys/net [netbsd-10]: nd.c

 Log Message:
 Pull up following revision(s) (requested by rin in ticket #827):

 	sys/net/nd.c: revision 1.6
 	sys/net/nd.c: revision 1.7

 nd_resolve: Maintain la_numheld.

 Otherwise lltable_drop_entry_queue never drops anything.

 Addresses mbuf leak, PR kern/58297.

 nd_timer: Update la_numheld when we clear la_hold (a.k.a. ln_hold).

 Followup for PR kern/58297 fix.  Patch by mlelstv@.
 PR kern/58301


 To generate a diff of this commit:
 cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/net/nd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: needs-pullups->closed
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Thu, 12 Sep 2024 13:23:54 +0000
State-Changed-Why:
fixed in HEAD, pulled up to 10, inapplicable <10


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.