git: 1af332a7d8f8 - main - rtsold: Fix validation of RDNSS options

Mark Johnston markj at FreeBSD.org
Sun Mar 21 18:19:54 UTC 2021


The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=1af332a7d8f86b6fcc1f0f575fe5b06021b54f4c

commit 1af332a7d8f86b6fcc1f0f575fe5b06021b54f4c
Author:     Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-03-21 18:18:10 +0000
Commit:     Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-03-21 18:19:42 +0000

    rtsold: Fix validation of RDNSS options
    
    The header specifies the size of the option in multiples of eight bytes.
    The option consists of an eight-byte header followed by one or more IPv6
    addresses, so the option is invalid if the size is not equal to 1+2n for
    some n>0.  Check this.
    
    The bug can cause random stack data to be formatted as an IPv6 address
    and passed to resolvconf(8), but a host able to trigger the bug may also
    specify arbitrary addresses this way.
    
    Reported by:    Q C <cq674350529 at gmail.com>
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
---
 usr.sbin/rtsold/rtsol.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index 30027fc65ac9..76756bfd8393 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -363,13 +363,19 @@ rtsol_input(int sock)
 		case ND_OPT_RDNSS:
 			rdnss = (struct nd_opt_rdnss *)raoptp;
 
-			/* Optlen sanity check (Section 5.3.1 in RFC 6106) */
-			if (rdnss->nd_opt_rdnss_len < 3) {
+			/*
+			 * The option header is 8 bytes long and each address
+			 * occupies 16 bytes, so the option length must be
+			 * greater than or equal to 24 bytes and an odd multiple
+			 * of 8 bytes.  See section 5.1 in RFC 6106.
+			 */
+			if (rdnss->nd_opt_rdnss_len < 3 ||
+			    rdnss->nd_opt_rdnss_len % 2 == 0) {
 				warnmsg(LOG_INFO, __func__,
-		    			"too short RDNSS option"
-					"in RA from %s was ignored.",
-					inet_ntop(AF_INET6, &from.sin6_addr,
-					    ntopbuf, sizeof(ntopbuf)));
+				    "too short RDNSS option in RA from %s "
+				    "was ignored.",
+				inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
+				    sizeof(ntopbuf)));
 				break;
 			}
 


More information about the dev-commits-src-main mailing list