prabhakar lakhera <prabhakar.lakh...@gmail.com> wrote
  in <CALg+rhX6L8HARzuWR=V429vO+tV7N=nx0b20vhrwaacrmpp...@mail.gmail.com>:

pr> Like I said before, it is not per RFC. It is trivial to derive solicited
pr> node multicast address from the target IP, so If someone were to launch a
pr> flood attack to poison cache entry for X host by sending Address resolution
pr> request for all other local hosts in the network, with NS's source IP=X's
pr> IP and with source link layer info=attacker's MAC, computing sol node
pr> multicast for each target will make it only slightly costly, so I am not
pr> sure if security could be of concern here.
pr>
pr> The other concern is if it can be a compliance issue given the NS packet
pr> format described by the RFC.
pr>
pr> Also the comment in the code suggests what RFC says but the check is more
pr> liberal. Also why it is different for DAD NS vs Neighbor resolution NS.

 In my understanding, RFC does not allow sending NS messages to
 all-node multicast address but says nothing about accepting side.  An
 NS message to all-node multicast address is broken, but at least
 FreeBSD never sends an NS message to all-node multicast address.
 There is no problem with RFC conformance in this regard.

 The check itself is easy and I think the attached patch is enough.  I
 am still wondering what kind of trouble we have if we do not do this
 check.

 I do not think the security concern is severe because NS flooding
 from neighbors is still easy even if narrowing down the destination
 address check upon its acceptance.  One possible countermeasure
 would be rate-limiting of NS/NA.

-- Hiroki
Index: sys/netinet6/nd6_nbr.c
===================================================================
--- sys/netinet6/nd6_nbr.c	(revision 273157)
+++ sys/netinet6/nd6_nbr.c	(working copy)
@@ -116,6 +116,7 @@
 	int lladdrlen = 0;
 	int anycast = 0, proxy = 0, tentative = 0;
 	int tlladdr;
+	int dsmaddr;
 	int rflag;
 	union nd_opts ndopts;
 	struct sockaddr_dl proxydl;
@@ -147,15 +148,33 @@
 		goto bad;
 	}

-	if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
-		/* dst has to be a solicited node multicast address. */
-		if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
+	/*
+	 * Attaching target link-layer address to the NA?
+	 * (RFC 2461 7.2.4)
+	 *
+	 * NS IP dst is unicast/anycast			MUST NOT add
+	 * NS IP dst is solicited-node multicast	MUST add
+	 *
+	 * In implementation, we add target link-layer address by default.
+	 * We do not add one in MUST NOT cases.
+	 */
+	if (!IN6_IS_ADDR_MULTICAST(&daddr6))
+		tlladdr = dsmaddr = 0;
+	else if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
 		    /* don't check ifindex portion */
 		    daddr6.s6_addr32[1] == 0 &&
 		    daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
-		    daddr6.s6_addr8[12] == 0xff) {
-			; /* good */
-		} else {
+		    daddr6.s6_addr8[12] == 0xff)
+		tlladdr = dsmaddr = 1;
+	else {
+		nd6log((LOG_INFO, "nd6_ns_input: multicast NS not to "
+		    "solicited-node multicast address.\n"));
+		goto bad;
+	}
+
+	if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
+		/* dst has to be a solicited node multicast address. */
+		if (dsmaddr == 0) {
 			nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
 			    "(wrong ip6 dst)\n"));
 			goto bad;
@@ -206,21 +225,6 @@
 	}

 	/*
-	 * Attaching target link-layer address to the NA?
-	 * (RFC 2461 7.2.4)
-	 *
-	 * NS IP dst is unicast/anycast			MUST NOT add
-	 * NS IP dst is solicited-node multicast	MUST add
-	 *
-	 * In implementation, we add target link-layer address by default.
-	 * We do not add one in MUST NOT cases.
-	 */
-	if (!IN6_IS_ADDR_MULTICAST(&daddr6))
-		tlladdr = 0;
-	else
-		tlladdr = 1;
-
-	/*
 	 * Target address (taddr6) must be either:
 	 * (1) Valid unicast/anycast address for my receiving interface,
 	 * (2) Unicast address for which I'm offering proxy service, or

Attachment: pgpB4OkjL6ohy.pgp
Description: PGP signature

Reply via email to