NetBSD Problem Report #60488

From www@netbsd.org  Thu Jul 23 19:31:23 2026
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)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.netbsd.org", Issuer "YR2" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 51E6D1A923B
	for <gnats-bugs@gnats.NetBSD.org>; Thu, 23 Jul 2026 19:31:23 +0000 (UTC)
Message-Id: <20260723193121.B10CD1A923C@mollari.NetBSD.org>
Date: Thu, 23 Jul 2026 19:31:21 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: nd6: two-byte buffer overread in source/target linkaddr options
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>

>Number:         60488
>Category:       kern
>Synopsis:       nd6: two-byte buffer overread in source/target linkaddr options
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          needs-pullups
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 23 19:35:00 +0000 2026
>Closed-Date:    
>Last-Modified:  Thu Jul 23 22:09:05 +0000 2026
>Originator:     Taylor R Campbell
>Release:        current, 11, 10, 9, ...
>Organization:
The NeighBSD Discoverflow, Inc.
>Environment:
>Description:
	In both nd6_ns_input and nd6_na_input, the option length in
	struct nd_opt_hdr::nd_opt_len is taken to be the length of the
	payload _excluding_ the headder, but what the protocol
	specifies, and what is verified in nd6.c, is that nd_opt_len is
	the length of the whole option _including_ the header:

    185 	if (ndopts.nd_opts_src_lladdr) {
    186 		lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
    187 		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
    188 	}

https://nxr.netbsd.org/xref/src/sys/netinet6/nd6_nbr.c?r=1.186#185

    678 	if (ndopts.nd_opts_tgt_lladdr != NULL) {
    679 		struct ifnet *ifp_ll;
    680 		struct psref psref_ll;
    681 
    682 		lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
    683 		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;

https://nxr.netbsd.org/xref/src/sys/netinet6/nd6_nbr.c?r=1.186#678

	This lladdrlen is later used as a source buffer size for
	sockaddr_dl_init:

    322 			if (lladdr != NULL)
    323 				sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
    324 				    ifp->if_index, ifp->if_type,
    325 				    NULL, 0, lladdr, lladdrlen);

https://nxr.netbsd.org/xref/src/sys/netinet6/nd6_nbr.c?r=1.186#322

    716 			if (lladdr != NULL)
    717 				sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
    718 				    ifp->if_index, ifp->if_type,
    719 				    NULL, 0, lladdr, lladdrlen);

https://nxr.netbsd.org/xref/src/sys/netinet6/nd6_nbr.c?r=1.186#716

	That can lead sockaddr_dl_init to read past the verified end of
	the option buffer by two bytes.

	Note: The ND_OPT_TARGET_LINKADDR case appears to check the
	lladdrlen against ((ifp->if_addrlen + 2 + 7) & ~7) exactly, so
	there is probably no overread in that case.

>How-To-Repeat:

	convince NetBSD to process an nd6 packet with
	ND_OPT_TARGET_LINKADDR

>Fix:

	subtract two from lladdrlen

>Release-Note:

>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60488 CVS commit: src/sys/netinet6
Date: Thu, 23 Jul 2026 19:52:48 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Jul 23 19:52:48 UTC 2026

 Modified Files:
 	src/sys/netinet6: nd6_nbr.c

 Log Message:
 nd6: Avoid buffer overread of link-layer address options.

 PR kern/60488: nd6: two-byte buffer overread in source/target
 linkaddr options


 To generate a diff of this commit:
 cvs rdiff -u -r1.186 -r1.187 src/sys/netinet6/nd6_nbr.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/60488 CVS commit: src/sys/netinet6
Date: Thu, 23 Jul 2026 20:25:49 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Jul 23 20:25:49 UTC 2026

 Modified Files:
 	src/sys/netinet6: nd6_nbr.c

 Log Message:
 nd6: Redo previous avoidance of buffer overread.

 Previous change invalidated two checks of the length:

     285 	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
     286 		nd6log(LOG_INFO, "lladdrlen mismatch for %s "
     287 		    "(if %d, NS packet %d)\n",
     288 		    IN6_PRINT(ip6buf, &taddr6),
     289 		    ifp->if_addrlen, lladdrlen - 2);
     290 		goto bad;
     291 	}

 https://nxr.netbsd.org/xref/src/sys/netinet6/nd6_nbr.c?r=1.186#285

     685 		if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
     686 			nd6log(LOG_INFO, "lladdrlen mismatch for %s "
     687 			    "(if %d, NA packet %d)\n",
     688 			    IN6_PRINT(ip6buf, &taddr6),
     689 			    ifp->if_addrlen, lladdrlen - 2);
     690 			goto bad;
     691 		}

 https://nxr.netbsd.org/xref/src/sys/netinet6/nd6_nbr.c?r=1.186#685

 Even if we readjust it for the checks, it's still basically wrong:
 the buffer may have extra padding in there to round it up to a
 multiple of eight bytes, so we have to know what the correct length
 is for the interface anyway.  And we do: it's ifp->if_addrlen.  So
 just use that, after verifying the option has enough space for an
 address of that length.

 To make sure there are no accidental references to the option length
 (including header) lying around, I've renamed the variable lladdrlen
 to lladdroptlen.

 PR kern/60488: nd6: two-byte buffer overread in source/target
 linkaddr options


 To generate a diff of this commit:
 cvs rdiff -u -r1.187 -r1.188 src/sys/netinet6/nd6_nbr.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: Thu, 23 Jul 2026 22:09:05 +0000
State-Changed-Why:
fixed in HEAD, needs pullup-11, pullup-10, pullup-9


>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.